continued with libcsp

This commit is contained in:
2024-05-31 10:43:16 +02:00
parent a6517eb420
commit 637d87756c
7 changed files with 1167 additions and 596 deletions

View File

@ -1,12 +1,303 @@
use std::ffi::CString;
use std::{thread, time::Duration};
use libcsp_rust::{csp_init, csp_print_func};
use libcsp_rust::{
csp_accept, csp_bind, csp_init, csp_listen, csp_read, csp_route_work, CspSocket, CSP_ANY,
};
/*
#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() {
println!("Hello, world!");
unsafe {
csp_init();
let c_str = CString::new("hello world\n").unwrap();
csp_print_func(c_str.as_ptr());
println!("CSP server example");
// SAFETY: We only call this once.
unsafe { csp_init() };
let csp_router_jh = thread::spawn(|| loop {
if let Err(e) = csp_route_work() {
match e {
libcsp_rust::CspError::TimedOut => continue,
e => {
println!("CSP router error: {:?}", e);
break;
}
}
}
});
server();
csp_router_jh.join().unwrap();
}
fn server() {
// Create socket with no specific socket options, e.g. accepts CRC32, HMAC, etc. if enabled
// during compilation
let mut csp_socket = CspSocket::default();
// Bind socket to all ports, e.g. all incoming connections will be handled here
csp_bind(&mut csp_socket, CSP_ANY);
// Create a backlog of 10 connections, i.e. up to 10 new connections can be queued
csp_listen(&mut csp_socket, 10);
// Wait for connections and then process packets on the connection
loop {
// Wait for a new connection, 10000 mS timeout
let conn = csp_accept(&mut csp_socket, Duration::from_millis(10000));
if conn.is_none() {
continue;
}
let mut conn = conn.unwrap();
// Read packets on connection, timout is 100 mS
// csp_packet_t *packet;
loop {
let packet = csp_read(&mut conn, Duration::from_millis(100));
if packet.is_none() {
break;
}
}
/*
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);
}
}