getting a bit further now
This commit is contained in:
parent
5b422d1615
commit
30666f8692
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -36,6 +36,12 @@ dependencies = [
|
|||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.155"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcsp-cargo-build"
|
name = "libcsp-cargo-build"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -48,6 +54,7 @@ name = "libcsp-rust"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"libc",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -15,235 +15,12 @@ use libcsp_rust::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MY_SERVER_PORT: i32 = 10;
|
const MY_SERVER_PORT: i32 = 10;
|
||||||
|
const TEST_MODE: bool = false;
|
||||||
const RUN_DURATION_IN_SECS: u32 = 3;
|
const RUN_DURATION_IN_SECS: u32 = 3;
|
||||||
|
|
||||||
const TEST_MODE: bool = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <csp/csp_debug.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <csp/csp.h>
|
|
||||||
#include <csp/drivers/usart.h>
|
|
||||||
#include <csp/drivers/can_socketcan.h>
|
|
||||||
#include <csp/interfaces/csp_if_zmqhub.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* These three functions must be provided in arch specific way */
|
|
||||||
int router_start(void);
|
|
||||||
int server_start(void);
|
|
||||||
int client_start(void);
|
|
||||||
|
|
||||||
/* Server port, the port the server listens on for incoming connections from the client. */
|
|
||||||
#define MY_SERVER_PORT 10
|
|
||||||
|
|
||||||
/* Commandline options */
|
|
||||||
static uint8_t server_address = 255;
|
|
||||||
|
|
||||||
/* test mode, used for verifying that host & client can exchange packets over the loopback interface */
|
|
||||||
static bool test_mode = false;
|
|
||||||
static unsigned int server_received = 0;
|
|
||||||
static unsigned int run_duration_in_sec = 3;
|
|
||||||
|
|
||||||
/* Server task - handles requests from clients */
|
|
||||||
void server(void) {
|
|
||||||
|
|
||||||
csp_print("Server task started\n");
|
|
||||||
|
|
||||||
/* Create socket with no specific socket options, e.g. accepts CRC32, HMAC, etc. if enabled during compilation */
|
|
||||||
csp_socket_t sock = {0};
|
|
||||||
|
|
||||||
/* Bind socket to all ports, e.g. all incoming connections will be handled here */
|
|
||||||
csp_bind(&sock, CSP_ANY);
|
|
||||||
|
|
||||||
/* Create a backlog of 10 connections, i.e. up to 10 new connections can be queued */
|
|
||||||
csp_listen(&sock, 10);
|
|
||||||
|
|
||||||
/* Wait for connections and then process packets on the connection */
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
/* Wait for a new connection, 10000 mS timeout */
|
|
||||||
csp_conn_t *conn;
|
|
||||||
if ((conn = csp_accept(&sock, 10000)) == NULL) {
|
|
||||||
/* timeout */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read packets on connection, timout is 100 mS */
|
|
||||||
csp_packet_t *packet;
|
|
||||||
while ((packet = csp_read(conn, 50)) != NULL) {
|
|
||||||
switch (csp_conn_dport(conn)) {
|
|
||||||
case MY_SERVER_PORT:
|
|
||||||
/* Process packet here */
|
|
||||||
csp_print("Packet received on MY_SERVER_PORT: %s\n", (char *) packet->data);
|
|
||||||
csp_buffer_free(packet);
|
|
||||||
++server_received;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Call the default CSP service handler, handle pings, buffer use, etc. */
|
|
||||||
csp_service_handler(packet);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close current connection */
|
|
||||||
csp_close(conn);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
/* End of server task */
|
|
||||||
|
|
||||||
/* Client task sending requests to server task */
|
|
||||||
void client(void) {
|
|
||||||
|
|
||||||
csp_print("Client task started\n");
|
|
||||||
|
|
||||||
unsigned int count = 'A';
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
usleep(test_mode ? 200000 : 1000000);
|
|
||||||
|
|
||||||
/* Send ping to server, timeout 1000 mS, ping size 100 bytes */
|
|
||||||
int result = csp_ping(server_address, 1000, 100, CSP_O_NONE);
|
|
||||||
csp_print("Ping address: %u, result %d [mS]\n", server_address, result);
|
|
||||||
(void) result;
|
|
||||||
|
|
||||||
/* Send reboot request to server, the server has no actual implementation of csp_sys_reboot() and fails to reboot */
|
|
||||||
csp_reboot(server_address);
|
|
||||||
csp_print("reboot system request sent to address: %u\n", server_address);
|
|
||||||
|
|
||||||
/* Send data packet (string) to server */
|
|
||||||
|
|
||||||
/* 1. Connect to host on 'server_address', port MY_SERVER_PORT with regular UDP-like protocol and 1000 ms timeout */
|
|
||||||
csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, server_address, MY_SERVER_PORT, 1000, CSP_O_NONE);
|
|
||||||
if (conn == NULL) {
|
|
||||||
/* Connect failed */
|
|
||||||
csp_print("Connection failed\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2. Get packet buffer for message/data */
|
|
||||||
csp_packet_t * packet = csp_buffer_get(100);
|
|
||||||
if (packet == NULL) {
|
|
||||||
/* Could not get buffer element */
|
|
||||||
csp_print("Failed to get CSP buffer\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3. Copy data to packet */
|
|
||||||
memcpy(packet->data, "Hello world ", 12);
|
|
||||||
memcpy(packet->data + 12, &count, 1);
|
|
||||||
memset(packet->data + 13, 0, 1);
|
|
||||||
count++;
|
|
||||||
|
|
||||||
/* 4. Set packet length */
|
|
||||||
packet->length = (strlen((char *) packet->data) + 1); /* include the 0 termination */
|
|
||||||
|
|
||||||
/* 5. Send packet */
|
|
||||||
csp_send(conn, packet);
|
|
||||||
|
|
||||||
/* 6. Close connection */
|
|
||||||
csp_close(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* End of client task */
|
|
||||||
|
|
||||||
static void print_usage(void)
|
|
||||||
{
|
|
||||||
csp_print("Usage:\n"
|
|
||||||
" -t enable test mode\n"
|
|
||||||
" -T <duration> enable test mode with running time in seconds\n"
|
|
||||||
" -h print help\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* main - initialization of CSP and start of server/client tasks */
|
|
||||||
int main(int argc, char * argv[]) {
|
|
||||||
|
|
||||||
uint8_t address = 0;
|
|
||||||
int opt;
|
|
||||||
while ((opt = getopt(argc, argv, "tT:h")) != -1) {
|
|
||||||
switch (opt) {
|
|
||||||
case 'a':
|
|
||||||
address = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
server_address = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
test_mode = true;
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
test_mode = true;
|
|
||||||
run_duration_in_sec = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
print_usage();
|
|
||||||
exit(0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
print_usage();
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
csp_print("Initialising CSP");
|
|
||||||
|
|
||||||
/* Init CSP */
|
|
||||||
csp_init();
|
|
||||||
|
|
||||||
/* Start router */
|
|
||||||
router_start();
|
|
||||||
|
|
||||||
/* Add interface(s) */
|
|
||||||
csp_iface_t * default_iface = NULL;
|
|
||||||
if (!default_iface) {
|
|
||||||
/* no interfaces configured - run server and client in process, using loopback interface */
|
|
||||||
server_address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
csp_print("Connection table\r\n");
|
|
||||||
csp_conn_print_table();
|
|
||||||
|
|
||||||
csp_print("Interfaces\r\n");
|
|
||||||
csp_iflist_print();
|
|
||||||
|
|
||||||
/* Start server thread */
|
|
||||||
server_start();
|
|
||||||
|
|
||||||
/* Start client thread */
|
|
||||||
client_start();
|
|
||||||
|
|
||||||
/* Wait for execution to end (ctrl+c) */
|
|
||||||
while(1) {
|
|
||||||
sleep(run_duration_in_sec);
|
|
||||||
|
|
||||||
if (test_mode) {
|
|
||||||
/* Test mode is intended for checking that host & client can exchange packets over loopback */
|
|
||||||
if (server_received < 5) {
|
|
||||||
csp_print("Server received %u packets\n", server_received);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
csp_print("Server received %u packets\n", server_received);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn main() -> Result<(), u32> {
|
fn main() -> Result<(), u32> {
|
||||||
println!("CSP server example");
|
println!("CSP client/server example");
|
||||||
|
|
||||||
// SAFETY: We only call this once.
|
// SAFETY: We only call this once.
|
||||||
unsafe { csp_init() };
|
unsafe { csp_init() };
|
||||||
|
|
||||||
@ -288,9 +65,7 @@ fn main() -> Result<(), u32> {
|
|||||||
let received_count = server_recv_copy.load(std::sync::atomic::Ordering::Relaxed);
|
let received_count = server_recv_copy.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
println!("CSP: Server received {} packets", received_count);
|
println!("CSP: Server received {} packets", received_count);
|
||||||
if received_count < 5 {
|
if received_count < 5 {
|
||||||
stop_signal.store(true, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
app_result = Err(1);
|
app_result = Err(1);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
stop_signal.store(true, std::sync::atomic::Ordering::Relaxed);
|
stop_signal.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
break;
|
break;
|
||||||
@ -327,21 +102,26 @@ fn server(server_received: Arc<AtomicU32>, stop_signal: Arc<AtomicBool>) {
|
|||||||
if conn.is_none() {
|
if conn.is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let conn = conn.unwrap();
|
println!("server accepted conn");
|
||||||
|
let mut conn = conn.unwrap();
|
||||||
|
|
||||||
// Read packets on connection, timout is 100 mS
|
// Read packets on connection, timout is 100 mS
|
||||||
loop {
|
loop {
|
||||||
if stop_signal.load(std::sync::atomic::Ordering::Relaxed) {
|
if stop_signal.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("server trying read");
|
||||||
// SAFETY: Connection is active while we read here.
|
// SAFETY: Connection is active while we read here.
|
||||||
let packet = unsafe { csp_read(conn.0, Duration::from_millis(100)) };
|
let packet = unsafe { csp_read(&mut conn.0, Duration::from_millis(100)) };
|
||||||
if packet.is_none() {
|
if packet.is_none() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
println!("server read a packet");
|
||||||
let mut packet = packet.unwrap();
|
let mut packet = packet.unwrap();
|
||||||
match csp_conn_dport(conn.0) {
|
match csp_conn_dport(&conn.0) {
|
||||||
MY_SERVER_PORT => {
|
MY_SERVER_PORT => {
|
||||||
|
println!("server received packet on custom port");
|
||||||
server_received.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
server_received.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
// Process packet here.
|
// Process packet here.
|
||||||
println!(
|
println!(
|
||||||
@ -350,6 +130,7 @@ fn server(server_received: Arc<AtomicU32>, stop_signal: Arc<AtomicBool>) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
println!("calling CSP service handler");
|
||||||
csp_service_handler(&mut packet);
|
csp_service_handler(&mut packet);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -371,6 +152,8 @@ fn client(stop_signal: Arc<AtomicBool>) {
|
|||||||
} else {
|
} else {
|
||||||
thread::sleep(Duration::from_millis(100));
|
thread::sleep(Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
|
println!("client trying to ping");
|
||||||
|
|
||||||
// Send ping to server, timeout 1000 mS, ping size 100 bytes
|
// Send ping to server, timeout 1000 mS, ping size 100 bytes
|
||||||
if let Err(e) = csp_ping(
|
if let Err(e) = csp_ping(
|
||||||
CSP_LOOPBACK,
|
CSP_LOOPBACK,
|
||||||
@ -401,7 +184,7 @@ fn client(stop_signal: Arc<AtomicBool>) {
|
|||||||
println!("CSP client: connection failed");
|
println!("CSP client: connection failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let conn = conn.unwrap();
|
let mut conn = conn.unwrap();
|
||||||
|
|
||||||
// 2. Get packet buffer for message/data.
|
// 2. Get packet buffer for message/data.
|
||||||
let packet_ref = csp_buffer_get();
|
let packet_ref = csp_buffer_get();
|
||||||
@ -409,7 +192,7 @@ fn client(stop_signal: Arc<AtomicBool>) {
|
|||||||
println!("CSP client: failed to get CSP buffer");
|
println!("CSP client: failed to get CSP buffer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut packet_ref = packet_ref.unwrap();
|
let mut packet_mut = packet_ref.unwrap();
|
||||||
|
|
||||||
// 3. Copy data to packet.
|
// 3. Copy data to packet.
|
||||||
let mut string_to_set = String::from("Hello world");
|
let mut string_to_set = String::from("Hello world");
|
||||||
@ -417,9 +200,9 @@ fn client(stop_signal: Arc<AtomicBool>) {
|
|||||||
string_to_set.push(current_letter);
|
string_to_set.push(current_letter);
|
||||||
current_letter = (current_letter as u8 + 1) as char;
|
current_letter = (current_letter as u8 + 1) as char;
|
||||||
string_to_set.push('\0');
|
string_to_set.push('\0');
|
||||||
packet_ref.set_data(string_to_set.as_bytes());
|
packet_mut.set_data(string_to_set.as_bytes());
|
||||||
|
|
||||||
// 4. Send data.
|
// 4. Send data.
|
||||||
csp_send(conn.0, packet_ref);
|
csp_send(&mut conn.0, packet_mut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1833
lib/bindings.rs
1833
lib/bindings.rs
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
git clone https://github.com/us-irs/libcsp.git
|
git clone https://github.com/us-irs/libcsp.git
|
||||||
git checkout 447cc38f2106a15290358dc8c128ad553a415568
|
git checkout const-correctness
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
bindgen --use-core wrapper.h -- "-I./libcsp/include" "-I./cfg" > bindings.rs
|
bindgen --use-core wrapper.h -- "-I./libcsp/include" "-I./cfg" "-I./libcsp/src" > bindings.rs
|
||||||
|
@ -1 +1,2 @@
|
|||||||
#include "csp/csp.h"
|
#include "csp/csp.h"
|
||||||
|
#include "csp_conn.h"
|
||||||
|
@ -7,3 +7,4 @@ links = "csp"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "2"
|
bitflags = "2"
|
||||||
num_enum = "0.7"
|
num_enum = "0.7"
|
||||||
|
libc = "0.2"
|
||||||
|
@ -26,11 +26,13 @@ pub struct csp_id_t {
|
|||||||
pub sport: u8,
|
pub sport: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct csp_conn_s {
|
pub struct csp_conn_s {
|
||||||
pub address: u8,
|
pub address: u8,
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[doc = " CSP Packet.\n\n This structure is constructed to fit with all interface and protocols to prevent the\n need to copy data (zero copy).\n\n .. note:: In most cases a CSP packet cannot be reused in case of send failure, because the\n \t\t\t lower layers may add additional data causing increased length (e.g. CRC32), convert\n \t\t\t the CSP id to different endian (e.g. I2C), etc.\n"]
|
#[doc = " CSP Packet.\n\n This structure is constructed to fit with all interface and protocols to prevent the\n need to copy data (zero copy).\n\n .. note:: In most cases a CSP packet cannot be reused in case of send failure, because the\n \t\t\t lower layers may add additional data causing increased length (e.g. CRC32), convert\n \t\t\t the CSP id to different endian (e.g. I2C), etc.\n"]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -156,6 +158,70 @@ pub type csp_socket_t = csp_socket_s;
|
|||||||
#[doc = " Forward declaration of connection structure"]
|
#[doc = " Forward declaration of connection structure"]
|
||||||
pub type csp_conn_t = csp_conn_s;
|
pub type csp_conn_t = csp_conn_s;
|
||||||
|
|
||||||
|
pub type atomic_int = u32;
|
||||||
|
|
||||||
|
#[doc = " Connection states"]
|
||||||
|
pub type csp_conn_state_t = ::core::ffi::c_uint;
|
||||||
|
|
||||||
|
#[doc = " Connection types"]
|
||||||
|
pub type csp_conn_type_t = ::core::ffi::c_uint;
|
||||||
|
|
||||||
|
#[doc = " RDP Connection states"]
|
||||||
|
pub type csp_rdp_state_t = ::core::ffi::c_uint;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub type csp_bin_sem_t = libc::sem_t;
|
||||||
|
|
||||||
|
#[doc = " RDP Connection"]
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct csp_rdp_t {
|
||||||
|
#[doc = "< Connection state"]
|
||||||
|
pub state: csp_rdp_state_t,
|
||||||
|
#[doc = "< Tracks 'who' have closed the RDP connection"]
|
||||||
|
pub closed_by: u8,
|
||||||
|
#[doc = "< The sequence number of the next segment that is to be sent"]
|
||||||
|
pub snd_nxt: u16,
|
||||||
|
#[doc = "< The sequence number of the oldest unacknowledged segment"]
|
||||||
|
pub snd_una: u16,
|
||||||
|
#[doc = "< The initial send sequence number"]
|
||||||
|
pub snd_iss: u16,
|
||||||
|
#[doc = "< The sequence number of the last segment received correctly and in sequence"]
|
||||||
|
pub rcv_cur: u16,
|
||||||
|
#[doc = "< The initial receive sequence number"]
|
||||||
|
pub rcv_irs: u16,
|
||||||
|
#[doc = "< The last sequence number acknowledged by the receiver"]
|
||||||
|
pub rcv_lsa: u16,
|
||||||
|
pub window_size: u32,
|
||||||
|
pub conn_timeout: u32,
|
||||||
|
pub packet_timeout: u32,
|
||||||
|
pub delayed_acks: u32,
|
||||||
|
pub ack_timeout: u32,
|
||||||
|
pub ack_delay_count: u32,
|
||||||
|
pub ack_timestamp: u32,
|
||||||
|
pub tx_wait: csp_bin_sem_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = " @brief Connection struct"]
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct csp_conn_s {
|
||||||
|
pub type_: atomic_int,
|
||||||
|
pub state: atomic_int,
|
||||||
|
pub idin: csp_id_t,
|
||||||
|
pub idout: csp_id_t,
|
||||||
|
pub sport_outgoing: u8,
|
||||||
|
pub rx_queue: csp_queue_handle_t,
|
||||||
|
pub rx_queue_static: csp_static_queue_t,
|
||||||
|
pub rx_queue_static_data:
|
||||||
|
[core::ffi::c_char; CSP_CONN_RXQUEUE_LEN * core::mem::size_of::<*const csp_packet_s>()],
|
||||||
|
pub callback: ::core::option::Option<unsafe extern "C" fn(packet: *mut csp_packet_t)>,
|
||||||
|
pub dest_socket: *mut csp_socket_t,
|
||||||
|
pub timestamp: u32,
|
||||||
|
pub opts: u32,
|
||||||
|
pub rdp: csp_rdp_t,
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[doc = " Error counters"]
|
#[doc = " Error counters"]
|
||||||
pub static mut csp_dbg_buffer_out: u8;
|
pub static mut csp_dbg_buffer_out: u8;
|
||||||
@ -216,7 +282,7 @@ extern "C" {
|
|||||||
) -> *mut csp_conn_t;
|
) -> *mut csp_conn_t;
|
||||||
|
|
||||||
#[doc = " Return destination port of connection.\n\n @param[in] conn connection\n @return destination port of an incoming connection"]
|
#[doc = " Return destination port of connection.\n\n @param[in] conn connection\n @return destination port of an incoming connection"]
|
||||||
pub fn csp_conn_dport(conn: *mut csp_conn_t) -> ::core::ffi::c_int;
|
pub fn csp_conn_dport(conn: *const csp_conn_t) -> ::core::ffi::c_int;
|
||||||
|
|
||||||
#[doc = " Get free buffer from task context.\n\n @param[in] unused OBSOLETE ignored field, csp packets have a fixed size now\n @return Buffer pointer to #csp_packet_t or NULL if no buffers available"]
|
#[doc = " Get free buffer from task context.\n\n @param[in] unused OBSOLETE ignored field, csp packets have a fixed size now\n @return Buffer pointer to #csp_packet_t or NULL if no buffers available"]
|
||||||
pub fn csp_buffer_get(unused: usize) -> *mut csp_packet_t;
|
pub fn csp_buffer_get(unused: usize) -> *mut csp_packet_t;
|
||||||
@ -228,6 +294,152 @@ extern "C" {
|
|||||||
pub fn csp_conn_print_table();
|
pub fn csp_conn_print_table();
|
||||||
|
|
||||||
pub fn csp_iflist_print();
|
pub fn csp_iflist_print();
|
||||||
|
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_csp_conn_s() {
|
||||||
|
const UNINIT: ::core::mem::MaybeUninit<csp_conn_s> = ::core::mem::MaybeUninit::uninit();
|
||||||
|
let ptr = UNINIT.as_ptr();
|
||||||
|
assert_eq!(
|
||||||
|
::core::mem::size_of::<csp_conn_s>(),
|
||||||
|
280usize,
|
||||||
|
concat!("Size of: ", stringify!(csp_conn_s))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::core::mem::align_of::<csp_conn_s>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Alignment of ", stringify!(csp_conn_s))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(type_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).state) as usize - ptr as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(state)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).idin) as usize - ptr as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(idin)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).idout) as usize - ptr as usize },
|
||||||
|
16usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(idout)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).sport_outgoing) as usize - ptr as usize },
|
||||||
|
24usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(sport_outgoing)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).rx_queue) as usize - ptr as usize },
|
||||||
|
32usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(rx_queue)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).rx_queue_static) as usize - ptr as usize },
|
||||||
|
40usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(rx_queue_static)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).rx_queue_static_data) as usize - ptr as usize },
|
||||||
|
48usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(rx_queue_static_data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).callback) as usize - ptr as usize },
|
||||||
|
176usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(callback)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).dest_socket) as usize - ptr as usize },
|
||||||
|
184usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(dest_socket)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).timestamp) as usize - ptr as usize },
|
||||||
|
192usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(timestamp)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).opts) as usize - ptr as usize },
|
||||||
|
196usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(opts)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).rdp) as usize - ptr as usize },
|
||||||
|
200usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(csp_conn_s),
|
||||||
|
"::",
|
||||||
|
stringify!(rdp)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -661,4 +873,39 @@ mod tests {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_sem_t() {
|
||||||
|
const UNINIT: ::core::mem::MaybeUninit<sem_t> = ::core::mem::MaybeUninit::uninit();
|
||||||
|
let ptr = UNINIT.as_ptr();
|
||||||
|
assert_eq!(
|
||||||
|
::core::mem::size_of::<sem_t>(),
|
||||||
|
32usize,
|
||||||
|
concat!("Size of: ", stringify!(sem_t))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::core::mem::align_of::<sem_t>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Alignment of ", stringify!(sem_t))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).__size) as usize - ptr as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(sem_t),
|
||||||
|
"::",
|
||||||
|
stringify!(__size)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ::core::ptr::addr_of!((*ptr).__align) as usize - ptr as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(sem_t),
|
||||||
|
"::",
|
||||||
|
stringify!(__align)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,32 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum ConnState {
|
||||||
|
Closed = 0,
|
||||||
|
Open = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum ConnType {
|
||||||
|
Client = 0,
|
||||||
|
Server = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum RdpState {
|
||||||
|
Closed = 0,
|
||||||
|
SynSent = 1,
|
||||||
|
SynRcvd = 2,
|
||||||
|
Open = 3,
|
||||||
|
CloseWait = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Copy, Clone, TryFromPrimitive, IntoPrimitive)]
|
||||||
|
#[repr(u8)]
|
||||||
pub enum MsgPriority {
|
pub enum MsgPriority {
|
||||||
Critical = 0,
|
Critical = 0,
|
||||||
High = 1,
|
High = 1,
|
||||||
@ -102,19 +127,53 @@ pub enum MsgPriority {
|
|||||||
|
|
||||||
pub struct CspPacket(pub csp_packet_s);
|
pub struct CspPacket(pub csp_packet_s);
|
||||||
|
|
||||||
pub struct CspPacketRef<'a>(&'a mut csp_packet_s);
|
pub struct CspPacketRef(*mut csp_packet_s);
|
||||||
|
|
||||||
impl<'a> CspPacketRef<'a> {
|
pub struct CspPacketMut(*mut csp_packet_s);
|
||||||
|
|
||||||
|
impl From<CspPacketMut> for CspPacketRef {
|
||||||
|
fn from(value: CspPacketMut) -> Self {
|
||||||
|
Self(value.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CspPacketRef {
|
||||||
pub fn packet_data(&self) -> &[u8] {
|
pub fn packet_data(&self) -> &[u8] {
|
||||||
unsafe { &self.0.packet_data_union.data[..self.packet_length()] }
|
unsafe { &(*self.0).packet_data_union.data[..self.packet_length()] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn whole_data(&self) -> &[u8; ffi::CSP_BUFFER_SIZE] {
|
pub fn whole_data(&self) -> &[u8; ffi::CSP_BUFFER_SIZE] {
|
||||||
unsafe { &self.0.packet_data_union.data }
|
unsafe { &(*self.0).packet_data_union.data }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn packet_length(&self) -> usize {
|
||||||
|
unsafe { (*self.0).length.into() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inner(&self) -> *const csp_packet_s {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CspPacketMut {
|
||||||
|
pub fn packet_data(&self) -> &[u8] {
|
||||||
|
unsafe { &(*self.0).packet_data_union.data[..self.packet_length()] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn whole_data(&self) -> &[u8; ffi::CSP_BUFFER_SIZE] {
|
||||||
|
unsafe { &(*self.0).packet_data_union.data }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn packet_length(&self) -> usize {
|
||||||
|
unsafe { (*self.0).length.into() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inner(&self) -> *const csp_packet_s {
|
||||||
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn whole_data_mut(&mut self) -> &mut [u8; ffi::CSP_BUFFER_SIZE] {
|
pub fn whole_data_mut(&mut self) -> &mut [u8; ffi::CSP_BUFFER_SIZE] {
|
||||||
unsafe { &mut self.0.packet_data_union.data }
|
unsafe { &mut (*self.0).packet_data_union.data }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_data(&mut self, data: &[u8]) -> bool {
|
pub fn set_data(&mut self, data: &[u8]) -> bool {
|
||||||
@ -122,19 +181,13 @@ impl<'a> CspPacketRef<'a> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
self.whole_data_mut()[0..data.len()].copy_from_slice(data);
|
self.whole_data_mut()[0..data.len()].copy_from_slice(data);
|
||||||
self.0.length = data.len() as u16;
|
unsafe {
|
||||||
|
(*self.0).length = data.len() as u16;
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packet_length(&self) -> usize {
|
pub fn inner_mut(&self) -> *mut csp_packet_s {
|
||||||
self.0.length.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inner(&self) -> *const csp_packet_s {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inner_mut(&self) -> *const csp_packet_s {
|
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,19 +268,9 @@ pub fn csp_route_work() -> Result<(), CspError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct CspConn(csp_conn_s);
|
pub struct CspConnRef(*mut csp_conn_s);
|
||||||
|
|
||||||
impl CspConn {
|
pub struct CspConnGuard(pub CspConnRef);
|
||||||
fn new(address: u8) -> Self {
|
|
||||||
Self(csp_conn_s { address })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn addr(&self) -> u8 {
|
|
||||||
self.0.address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CspConnGuard(pub CspConn);
|
|
||||||
|
|
||||||
impl Drop for CspConnGuard {
|
impl Drop for CspConnGuard {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@ -235,14 +278,14 @@ impl Drop for CspConnGuard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<CspConn> for CspConnGuard {
|
impl AsRef<CspConnRef> for CspConnGuard {
|
||||||
fn as_ref(&self) -> &CspConn {
|
fn as_ref(&self) -> &CspConnRef {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsMut<CspConn> for CspConnGuard {
|
impl AsMut<CspConnRef> for CspConnGuard {
|
||||||
fn as_mut(&mut self) -> &mut CspConn {
|
fn as_mut(&mut self) -> &mut CspConnRef {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,17 +295,17 @@ pub fn csp_accept_guarded(socket: &mut CspSocket, timeout: Duration) -> Option<C
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_accept].
|
/// Rust wrapper for [ffi::csp_accept].
|
||||||
pub fn csp_accept(socket: &mut CspSocket, timeout: Duration) -> Option<CspConn> {
|
pub fn csp_accept(socket: &mut CspSocket, timeout: Duration) -> Option<CspConnRef> {
|
||||||
let timeout_millis = timeout.as_millis();
|
let timeout_millis = timeout.as_millis();
|
||||||
if timeout_millis > u32::MAX as u128 {
|
if timeout_millis > u32::MAX as u128 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(CspConn::new(unsafe {
|
Some(CspConnRef(unsafe {
|
||||||
let addr = ffi::csp_accept(socket.inner_as_mut_ptr(), timeout_millis as u32);
|
let addr = ffi::csp_accept(socket.inner_as_mut_ptr(), timeout_millis as u32);
|
||||||
if addr.is_null() {
|
if addr.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
(*addr).address
|
addr
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,12 +314,12 @@ pub fn csp_accept(socket: &mut CspSocket, timeout: Duration) -> Option<CspConn>
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - You MUST ensure that a connection is active when calling this function.
|
/// - You MUST ensure that a connection is active when calling this function.
|
||||||
pub unsafe fn csp_read<'a>(mut conn: CspConn, timeout: Duration) -> Option<CspPacketRef<'a>> {
|
pub unsafe fn csp_read(conn: &mut CspConnRef, timeout: Duration) -> Option<CspPacketRef> {
|
||||||
let timeout_millis = timeout.as_millis();
|
let timeout_millis = timeout.as_millis();
|
||||||
if timeout_millis > u32::MAX as u128 {
|
if timeout_millis > u32::MAX as u128 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let opt_packet = unsafe { ffi::csp_read(&mut conn.0, timeout_millis as u32) };
|
let opt_packet = unsafe { ffi::csp_read(conn.0, timeout_millis as u32) };
|
||||||
if opt_packet.is_null() {
|
if opt_packet.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -285,9 +328,9 @@ pub unsafe fn csp_read<'a>(mut conn: CspConn, timeout: Duration) -> Option<CspPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_conn_dport].
|
/// Rust wrapper for [ffi::csp_conn_dport].
|
||||||
pub fn csp_conn_dport(mut conn: CspConn) -> i32 {
|
pub fn csp_conn_dport(conn: &CspConnRef) -> i32 {
|
||||||
// SAFETY: FFI call.
|
// SAFETY: FFI call.
|
||||||
unsafe { ffi::csp_conn_dport(&mut conn.0) }
|
unsafe { ffi::csp_conn_dport(conn.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn csp_service_handler(packet: &mut CspPacketRef) {
|
pub fn csp_service_handler(packet: &mut CspPacketRef) {
|
||||||
@ -296,9 +339,9 @@ pub fn csp_service_handler(packet: &mut CspPacketRef) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_close].
|
/// Rust wrapper for [ffi::csp_close].
|
||||||
pub fn csp_close(mut conn: CspConn) -> i32 {
|
pub fn csp_close(conn: CspConnRef) -> i32 {
|
||||||
// SAFETY: FFI call.
|
// SAFETY: FFI call.
|
||||||
unsafe { ffi::csp_close(&mut conn.0) }
|
unsafe { ffi::csp_close(conn.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_ping], returns the result code directly.
|
/// Rust wrapper for [ffi::csp_ping], returns the result code directly.
|
||||||
@ -342,7 +385,7 @@ pub fn csp_connect(
|
|||||||
dst_port: u8,
|
dst_port: u8,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
opts: ConnectOpts,
|
opts: ConnectOpts,
|
||||||
) -> Option<CspConn> {
|
) -> Option<CspConnRef> {
|
||||||
// SAFETY: FFI call.
|
// SAFETY: FFI call.
|
||||||
let conn = unsafe {
|
let conn = unsafe {
|
||||||
ffi::csp_connect(
|
ffi::csp_connect(
|
||||||
@ -357,7 +400,7 @@ pub fn csp_connect(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// SAFETY: We checked that the pointer is valid.
|
// SAFETY: We checked that the pointer is valid.
|
||||||
Some(CspConn::new(unsafe { *conn }.address))
|
Some(CspConnRef(conn))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_connect] which returns a guard structure. The connection will be
|
/// Rust wrapper for [ffi::csp_connect] which returns a guard structure. The connection will be
|
||||||
@ -375,7 +418,7 @@ pub fn csp_connect_guarded(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_buffer_get].
|
/// Rust wrapper for [ffi::csp_buffer_get].
|
||||||
pub fn csp_buffer_get() -> Option<CspPacketRef<'static>> {
|
pub fn csp_buffer_get() -> Option<CspPacketMut> {
|
||||||
let packet_ref = unsafe {
|
let packet_ref = unsafe {
|
||||||
// The size argument is unused
|
// The size argument is unused
|
||||||
ffi::csp_buffer_get(0)
|
ffi::csp_buffer_get(0)
|
||||||
@ -384,13 +427,13 @@ pub fn csp_buffer_get() -> Option<CspPacketRef<'static>> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// SAFETY: We checked that the pointer is valid.
|
// SAFETY: We checked that the pointer is valid.
|
||||||
Some(CspPacketRef(unsafe { &mut *packet_ref }))
|
Some(CspPacketMut(unsafe { &mut *packet_ref }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_send].
|
/// Rust wrapper for [ffi::csp_send].
|
||||||
pub fn csp_send(mut conn: CspConn, packet: CspPacketRef) {
|
pub fn csp_send(conn: &mut CspConnRef, packet: impl Into<CspPacketRef>) {
|
||||||
// SAFETY: FFI call.
|
// SAFETY: FFI call.
|
||||||
unsafe { ffi::csp_send(&mut conn.0, packet.0) }
|
unsafe { ffi::csp_send(conn.0, packet.into().0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rust wrapper for [ffi::csp_conn_print_table].
|
/// Rust wrapper for [ffi::csp_conn_print_table].
|
||||||
|
Loading…
Reference in New Issue
Block a user