let's try to wrap this up
This commit is contained in:
@ -2,20 +2,10 @@ libcsp-rust
|
||||
========
|
||||
|
||||
This crate provides a (mostly) safe and ergonomic Rust API for the
|
||||
[`libcsp` library](https://github.com/libcsp/libcsp) on top of the `libcsp-sys`
|
||||
crate. You can find some more high-level information and examples in the
|
||||
[`libcsp` library](https://github.com/libcsp/libcsp) on top of the
|
||||
[`libcsp-sys`](https://crates.io/crates/libcsp-sys) crate.
|
||||
|
||||
You can find some more high-level information and examples in the
|
||||
[main repository](https://egit.irs.uni-stuttgart.de/rust/libcsp-rust).
|
||||
|
||||
The API documentation should provide all additional information required to use this library.
|
||||
|
||||
## Compile-time configuration of the `libcsp-rust` library
|
||||
|
||||
The `libcsp-rust` library requires some compile-time configuration file to be included to work
|
||||
properly. You can see an example version of the file for the workspace
|
||||
[here](https://egit.irs.uni-stuttgart.de/rust/libcsp-rust/src/branch/main/examples/autoconfig.rs).
|
||||
The user has to provide the path to a directory containing this `autoconfig.rs` file using the
|
||||
`CSP_CONFIG_DIR` environmental variable.
|
||||
|
||||
It is recommended to read the [main workspace README](https://egit.irs.uni-stuttgart.de/rust/libcsp-rust)
|
||||
for more information to make the generation and specification of this auto-configuration file
|
||||
as conveniently and easy as possible.
|
||||
|
@ -1,5 +1,10 @@
|
||||
//! This crate provides a (mostly) safe and ergonomic Rust API for the
|
||||
//! [`libcsp` C library](https://github.com/libcsp/libcsp) on top of the
|
||||
//! [`libcsp-sys`](https://crates.io/crates/libcsp-sys) crate.
|
||||
//!
|
||||
//! You can find some more high-level information and examples in the
|
||||
//! [main repository](https://egit.irs.uni-stuttgart.de/rust/libcsp-rust).
|
||||
#![no_std]
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
#[cfg(any(feature = "std", test))]
|
||||
@ -11,7 +16,7 @@ use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use ffi::{csp_conn_s, csp_packet_s, csp_socket_s};
|
||||
use libcsp_sys as ffi;
|
||||
pub use libcsp_sys as ffi;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum ReservedPort {
|
||||
@ -291,6 +296,18 @@ pub fn csp_route_work() -> Result<(), CspError> {
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct CspConnRef(*mut csp_conn_s);
|
||||
|
||||
impl CspConnRef {
|
||||
pub fn inner(&mut self) -> Option<&csp_conn_s> {
|
||||
// SAFETY: Raw pointer access, we return [None] if the pointers is NULL.
|
||||
unsafe { self.0.as_ref() }
|
||||
}
|
||||
|
||||
pub fn inner_mut(&mut self) -> Option<&mut csp_conn_s> {
|
||||
// SAFETY: Raw pointer access, we return [None] if the pointers is NULL.
|
||||
unsafe { self.0.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CspConnGuard(pub CspConnRef);
|
||||
|
||||
impl Drop for CspConnGuard {
|
||||
@ -311,6 +328,57 @@ impl AsMut<CspConnRef> for CspConnGuard {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CspInterface(pub ffi::csp_iface_t);
|
||||
|
||||
impl CspInterface {
|
||||
pub fn new(host_addr: u16, is_default: bool) -> Self {
|
||||
Self(ffi::csp_iface_t {
|
||||
addr: host_addr,
|
||||
netmask: Default::default(),
|
||||
name: core::ptr::null(),
|
||||
interface_data: core::ptr::null_mut(),
|
||||
driver_data: core::ptr::null_mut(),
|
||||
nexthop: None,
|
||||
is_default: is_default as u8,
|
||||
tx: Default::default(),
|
||||
rx: Default::default(),
|
||||
tx_error: Default::default(),
|
||||
rx_error: Default::default(),
|
||||
drop: Default::default(),
|
||||
autherr: Default::default(),
|
||||
frame: Default::default(),
|
||||
txbytes: Default::default(),
|
||||
rxbytes: Default::default(),
|
||||
irq: Default::default(),
|
||||
next: core::ptr::null_mut(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CspUdpConf(pub ffi::csp_if_udp_conf_t);
|
||||
|
||||
impl CspUdpConf {
|
||||
pub fn new(addr: &'static str, lport: u16, rport: u16) -> Self {
|
||||
Self(ffi::csp_if_udp_conf_t {
|
||||
host: addr.as_ptr() as *mut i8,
|
||||
lport: lport.into(),
|
||||
rport: rport.into(),
|
||||
server_handle: Default::default(),
|
||||
peer_addr: libc::sockaddr_in {
|
||||
sin_family: Default::default(),
|
||||
sin_port: Default::default(),
|
||||
sin_addr: libc::in_addr {
|
||||
s_addr: Default::default(),
|
||||
},
|
||||
sin_zero: Default::default(),
|
||||
},
|
||||
sockfd: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn csp_accept_guarded(socket: &mut CspSocket, timeout: Duration) -> Option<CspConnGuard> {
|
||||
Some(CspConnGuard(csp_accept(socket, timeout)?))
|
||||
}
|
||||
@ -371,6 +439,41 @@ pub fn csp_conn_dport(conn: &CspConnRef) -> i32 {
|
||||
unsafe { ffi::csp_conn_dport(conn.0) }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_conn_sport].
|
||||
pub fn csp_conn_sport(conn: &CspConnRef) -> i32 {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::csp_conn_sport(conn.0) }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_conn_dst].
|
||||
pub fn csp_conn_dst(conn: &CspConnRef) -> i32 {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::csp_conn_dst(conn.0) }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_conn_src].
|
||||
pub fn csp_conn_src(conn: &CspConnRef) -> i32 {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::csp_conn_src(conn.0) }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_conn_src].
|
||||
pub fn csp_conn_flags(conn: &CspConnRef) -> i32 {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::csp_conn_flags(conn.0) }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_conn_src] which also tries to convert the options to
|
||||
/// a [ConnectOpts] bitfield.
|
||||
pub fn csp_conn_flags_typed(conn: &CspConnRef) -> Option<ConnectOpts> {
|
||||
let flags_raw = csp_conn_flags(conn);
|
||||
if flags_raw < 0 {
|
||||
return None;
|
||||
}
|
||||
// SAFETY: FFI call.
|
||||
ConnectOpts::from_bits(flags_raw as u32)
|
||||
}
|
||||
|
||||
pub fn csp_service_handler(packet: CspPacketRef) {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::csp_service_handler(&mut *packet.0) }
|
||||
@ -482,12 +585,6 @@ pub fn csp_conn_print_table() {
|
||||
unsafe { ffi::csp_conn_print_table() }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_iflist_print].
|
||||
pub fn csp_iflist_print() {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::csp_iflist_print() }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::csp_buffer_free].
|
||||
pub fn csp_buffer_free(packet: impl Into<CspPacketRef>) {
|
||||
// SAFETY: FFI call and the Rust type system actually ensure the correct type
|
||||
@ -557,3 +654,49 @@ pub fn csp_transaction_w_opts(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls [csp_transaction_w_opts] with [ConnectOpts::NONE].
|
||||
pub fn csp_transaction(
|
||||
prio: MsgPriority,
|
||||
dst: u16,
|
||||
dst_port: u8,
|
||||
timeout: Duration,
|
||||
out_data: &[u8],
|
||||
in_data: &mut [u8],
|
||||
in_len: Option<usize>,
|
||||
) -> i32 {
|
||||
csp_transaction_w_opts(
|
||||
prio,
|
||||
dst,
|
||||
dst_port,
|
||||
timeout,
|
||||
out_data,
|
||||
in_data,
|
||||
in_len,
|
||||
ConnectOpts::NONE,
|
||||
)
|
||||
}
|
||||
|
||||
pub mod udp {
|
||||
use super::*;
|
||||
|
||||
/// Rust wrapper for [ffi::udp::csp_if_udp_init].
|
||||
pub fn csp_if_udp_init(iface: &mut CspInterface, ifconf: &mut CspUdpConf) {
|
||||
unsafe { ffi::udp::csp_if_udp_init(&mut iface.0, &mut ifconf.0) }
|
||||
}
|
||||
}
|
||||
|
||||
pub mod iflist {
|
||||
use super::*;
|
||||
|
||||
/// Rust wrapper for [ffi::iflist::csp_iflist_print].
|
||||
pub fn csp_iflist_print() {
|
||||
// SAFETY: FFI call.
|
||||
unsafe { ffi::iflist::csp_iflist_print() }
|
||||
}
|
||||
|
||||
/// Rust wrapper for [ffi::iflist::csp_iflist_add].
|
||||
pub fn csp_iflist_add(iface: &mut CspInterface) -> i32 {
|
||||
unsafe { ffi::iflist::csp_iflist_add(&mut iface.0) }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user