continued with libcsp
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user