Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
34aebeb
service: peek/poke v2 with 64 bit memory support
Lykkeberg Aug 7, 2024
bb8110c
cmp: correct poke/peek length check for v2
edvardxyz Oct 8, 2024
794b257
Use struct initializer to avoid "unintialized value" Valgrind warning
kivkiv12345 Dec 10, 2024
7ba36fb
Fix a couple more sources of unitialized values
kivkiv12345 Dec 11, 2024
67cf50e
Fixed compilantion in release mode
ievel1 Jan 15, 2025
f0835bf
Allow CAN broadcast reception when not configuring interface to promisc
troelsjessen Apr 8, 2025
92067a4
Fix CSP v1 over CAN
troelsjessen May 13, 2025
f0d70fa
WIP: NOCOMMIT remove clone of unnecessary bytes in csp_buffer_clone
MErdbruegger Jun 1, 2025
cb3f265
Merge pull request #28 from MErdbruegger/csp_buffer_remove_unnecessar…
edvardxyz Jun 2, 2025
9306f2b
check timeout even if userspace
edvardxyz Jun 2, 2025
e96c578
Merge pull request #29 from spaceinventor/rdp_check_timeout
edvardxyz Jun 6, 2025
699ac52
csp_buffer: Fix pointers in csp_buffer_clone
edvardxyz Jun 6, 2025
42855ef
buffer: Ensure buffer allocation respect the reserve
edvardxyz Jun 6, 2025
983ee9e
Fix off-by-one in `csp_rtable_set()`
kivkiv12345 Jul 31, 2025
2cde83b
Fix `sec_key` valgrind warning in `csp_zmqhub_init_filter2()`
kivkiv12345 Aug 9, 2025
d419698
Use `CSP_IFLIST_NAME_MAX` for iface name len in `csp_rtable_parse()`
kivkiv12345 Aug 10, 2025
a8e72cd
Post init promisc config (#30)
kivkiv12345 Aug 13, 2025
60e4804
Improve some comments for `csp_zmqhub_<add/remove>_filters()`
kivkiv12345 Sep 8, 2025
8cc13c6
Add function to get iface from broadcast node
troelsjessen Oct 18, 2025
aed4576
Support for CSP alias
troelsjessen Oct 23, 2025
5a95e5c
Add alias support to ZMQ
troelsjessen Nov 3, 2025
3bc0c2d
Strip default options not read until meson 1.8
troelsjessen Nov 13, 2025
289cbcd
Update meson build to generate pkg-config files when installing
jeanbaptistelab Dec 4, 2025
fb9d552
Update to use meson installation tags
jeanbaptistelab Dec 4, 2025
52c9da1
Compile cleanly on both ARM and x86
jeanbaptistelab Dec 19, 2025
f3089f4
Use soname meson feature
jeanbaptistelab Dec 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/csp/csp.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,11 @@ void csp_rdp_get_opt(unsigned int *window_size, unsigned int *conn_timeout_ms,
unsigned int *ack_timeout, unsigned int *ack_delay_count);

/**
* Set platform specific memory copy function.
* Set platform specific memory copy functions.
*/
void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc);
void csp_cmp_set_memread64(csp_memread64_fnc_t fnc);
void csp_cmp_set_memwrite64(csp_memwrite64_fnc_t fnc);

#if (CSP_ENABLE_CSP_PRINT)

Expand Down
52 changes: 52 additions & 0 deletions include/csp/csp_cmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ extern "C" {
* Set/configure routing.
*/
#define CSP_CMP_ROUTE_SET_V2 7
/**
* Peek/read data from memory - 64-bit version.
*/
#define CSP_CMP_PEEK_V2 8
/**
* Poke/write data from memory - 64-bit version.
*/
#define CSP_CMP_POKE_V2 9
/**@}*/

/**
Expand Down Expand Up @@ -92,6 +100,16 @@ extern "C" {
*/
#define CSP_CMP_POKE_MAX_LEN 200

/**
* CMP peek/read memory - max read length - 64-bit.
*/
#define CSP_CMP_PEEK_V2_MAX_LEN 196

/**
* CMP poke/write memory - max write length - 64-bit.
*/
#define CSP_CMP_POKE_V2_MAX_LEN 196

/**
* CSP management protocol description.
*/
Expand Down Expand Up @@ -142,6 +160,16 @@ struct csp_cmp_message {
uint8_t len;
char data[CSP_CMP_POKE_MAX_LEN];
} poke;
struct {
uint64_t vaddr; /* Virtual 64-bit address on the target system */
uint8_t len;
char data[CSP_CMP_PEEK_V2_MAX_LEN];
} peek_v2;
struct {
uint64_t vaddr; /* Virtual 64-bit address on the target system */
uint8_t len;
char data[CSP_CMP_POKE_V2_MAX_LEN];
} poke_v2;
csp_timestamp_t clock;
};
} __attribute__((__packed__));
Expand Down Expand Up @@ -201,6 +229,30 @@ static inline int csp_cmp_poke(uint16_t node, uint32_t timeout, struct csp_cmp_m
return csp_cmp(node, timeout, CSP_CMP_POKE, CMP_SIZE(poke) - sizeof(msg->poke.data) + msg->poke.len, msg);
}

/**
* Peek (read) memory on remote node - 64-bit version.
*
* @param[in] node address of subsystem.
* @param[in] timeout timeout in mS to wait for reply..
* @param[in/out] msg memory address and number of bytes to peek. (msg peeked/read memory)
* @return #CSP_ERR_NONE on success, otherwise an error code.
*/
static inline int csp_cmp_peek_v2(uint16_t node, uint32_t timeout, struct csp_cmp_message *msg) {
return csp_cmp(node, timeout, CSP_CMP_PEEK_V2, CMP_SIZE(peek_v2) - sizeof(msg->peek_v2.data) + msg->peek_v2.len, msg);
}

/**
* Poke (write) memory on remote node - 64-bit version.
*
* @param[in] node address of subsystem.
* @param[in] timeout timeout in mS to wait for reply..
* @param[in] msg memory address, number of bytes and the actual bytes to poke/write.
* @return #CSP_ERR_NONE on success, otherwise an error code.
*/
static inline int csp_cmp_poke_v2(uint16_t node, uint32_t timeout, struct csp_cmp_message *msg) {
return csp_cmp(node, timeout, CSP_CMP_POKE_V2, CMP_SIZE(poke_v2) - sizeof(msg->poke_v2.data) + msg->poke_v2.len, msg);
}

#ifdef __cplusplus
}
#endif
4 changes: 4 additions & 0 deletions include/csp/csp_iflist.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ void csp_iflist_remove(csp_iface_t * ifc);

csp_iface_t * csp_iflist_get_by_name(const char * name);
csp_iface_t * csp_iflist_get_by_addr(uint16_t addr);
csp_iface_t * csp_iflist_get_by_broadcast(uint16_t addr);
csp_iface_t * csp_iflist_get_by_subnet(uint16_t addr, csp_iface_t * from);
csp_iface_t * csp_iflist_get_by_isdfl(csp_iface_t * ifc);
csp_iface_t * csp_iflist_get_by_index(int idx);
int csp_iflist_is_within_subnet(uint16_t addr, csp_iface_t * ifc);

csp_iface_t * csp_iflist_get(void);

int csp_addr_is_alias(uint16_t addr);
int csp_alias_add(csp_alias_t * addr);

/**
* Convert bytes to readable string
*/
Expand Down
14 changes: 14 additions & 0 deletions include/csp/csp_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern "C" {
* @return #CSP_ERR_NONE on success, otherwise an error code.
*/
typedef int (*nexthop_t)(csp_iface_t * iface, uint16_t via, csp_packet_t * packet, int from_me);
typedef int (*csp_alias_add_t)(void * driver_data, uint16_t addr);

/**
* This struct is referenced in documentation.
Expand All @@ -33,6 +34,7 @@ struct csp_iface_s {
void * interface_data; /**< Interface data, only known/used by the interface layer, e.g. state information. */
void * driver_data; /**< Driver data, only known/used by the driver layer, e.g. device/channel references. */
nexthop_t nexthop; /**< Next hop (Tx) function */
csp_alias_add_t add_alias; /**< Add receive address to interface (could be multicast receptions) */
uint8_t is_default; /**< Set default IF flag (CSP supports multiple defaults) */

/* Stats */
Expand All @@ -52,6 +54,18 @@ struct csp_iface_s {

};

/**
* Used to represent an alias reception address, bound to a particular interface
*/
typedef struct csp_alias_s {
uint16_t addr;
csp_iface_t * iface;

/* For linked lists*/
struct csp_alias_s * next;

} csp_alias_t;

/**
* Inputs a new packet into the system.
*
Expand Down
4 changes: 4 additions & 0 deletions include/csp/csp_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,16 @@ typedef const uint32_t csp_const_memptr_t;
typedef void * csp_memptr_t;
/** Const memory pointer */
typedef const void * csp_const_memptr_t;
/** Memory pointer 64-bit */
typedef uint64_t csp_memptr64_t;
#endif

/**
* Platform specific memory copy function.
*/
typedef csp_memptr_t (*csp_memcpy_fnc_t)(csp_memptr_t, csp_const_memptr_t, size_t);
typedef csp_memptr64_t (*csp_memread64_fnc_t)(csp_const_memptr_t, csp_memptr64_t, size_t);
typedef csp_memptr64_t (*csp_memwrite64_fnc_t)(csp_memptr64_t, csp_memptr_t, size_t);

/**
* Compile check/asserts.
Expand Down
15 changes: 15 additions & 0 deletions include/csp/interfaces/csp_if_zmqhub.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,21 @@ int csp_zmqhub_init_w_name_endpoints_rxfilter(const char * ifname, uint16_t addr
int csp_zmqhub_init_filter2(const char * ifname, const char * host, uint16_t addr, uint16_t netmask, int promisc, csp_iface_t ** return_interface, char * sec_key, uint16_t subport, uint16_t pubport);


/**
* Make `zmq_iface` promiscuous (parse all packets)
*
* Safe to call after `csp_zmqhub_init_filter2()` to change promiscuity.
*/
void csp_zmqhub_remove_filters(csp_iface_t * zmq_iface);

/**
* Make `zmq_iface` unpromiscuous, only parse matching unicast and broadcast addresses.
*
* Safe to call after `csp_zmqhub_init_filter2()` to change promiscuity.
*/
void csp_zmqhub_add_filters(csp_iface_t * zmq_iface);


#ifdef __cplusplus
}
#endif
2 changes: 1 addition & 1 deletion include/csp/meson.build
Original file line number Diff line number Diff line change
@@ -1 +1 @@
csp_config_h = configure_file(output: 'autoconfig.h', configuration: conf, install_dir: 'include/csp/')
csp_config_h = configure_file(output: 'autoconfig.h', configuration: conf, install_dir: 'include/csp/', install_tag: 'devel')
14 changes: 5 additions & 9 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
project('csp', 'c', version: '2.1', license: 'LGPL', meson_version : '>=0.53.2', default_options : [
'c_std=gnu11',
'optimization=s',
'warning_level=2',
'werror=true'])

Expand Down Expand Up @@ -69,19 +67,14 @@ csp_c_args = ['-Wshadow',
subdir('src')
subdir('include/csp')

if not meson.is_subproject()
install_subdir('include', install_dir : '.')
install_headers(csp_config_h, install_dir : 'include/csp')
endif


csp_lib = library('csp',
sources: [csp_sources, csp_config_h],
include_directories : csp_inc,
dependencies : csp_deps,
c_args : csp_c_args,
install : false,
install : true,
pic:true,
soversion: meson.project_version()
)

# The following dependency variable is for parent projects to link
Expand All @@ -91,6 +84,9 @@ csp_dep = declare_dependency(
link_with : csp_lib,
dependencies : csp_deps,
)
install_subdir('include', install_dir : '.', exclude_files: ['csp/meson.build'], install_tag: 'devel')
pkg = import('pkgconfig')
pkg.generate(csp_lib)

subdir('examples')

Expand Down
7 changes: 4 additions & 3 deletions src/csp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ static csp_packet_t * csp_buffer_get_actual(int reserve, int isr) {
} else {
remain = csp_queue_size(csp_buffers);
}
/* Respect if remaining is lower than the reserve requested */
if (remain < reserve) {
/* Respect the requested reserve */
if (remain <= reserve) {
return NULL;
}

Expand Down Expand Up @@ -139,8 +139,9 @@ void * csp_buffer_clone(void * buffer) {

csp_packet_t * clone = csp_buffer_get(packet->length);
if (clone) {
size_t size = sizeof(csp_packet_t) - CSP_BUFFER_SIZE + CSP_PACKET_PADDING_BYTES + packet->length;
size_t size = sizeof(csp_packet_t) - CSP_BUFFER_SIZE + packet->length;
memcpy(clone, packet, size > sizeof(csp_packet_t) ? sizeof(csp_packet_t) : size);
clone->frame_begin = (clone->header + CSP_PACKET_PADDING_BYTES) - (packet->data - packet->frame_begin);
}

return clone;
Expand Down
4 changes: 2 additions & 2 deletions src/csp_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,13 @@ csp_conn_t * csp_connect(uint8_t prio, uint16_t dest, uint8_t dport, uint32_t ti
opts |= csp_conf.conn_dfl_so;

/* Generate identifier */
csp_id_t incoming_id, outgoing_id;
csp_id_t incoming_id = {0}, outgoing_id = {0};

/* Use 0 as incoming id (this disables the input filter on destination node)
* This means that for this outgoing connection, we accept the answer coming to whatever address
* the outgoing interface has. CSP does not support "source address" on outgoing connections
* so the outgoing source address will be automatically applied after outgoing routing
* selects which interface the packet will leavve from */
* selects which interface the packet will leave from */
incoming_id.dst = 0;
outgoing_id.src = 0;

Expand Down
58 changes: 57 additions & 1 deletion src/csp_iflist.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#include <csp/csp_debug.h>
#include <csp/interfaces/csp_if_lo.h>

/* Interfaces are stored in a linked list */
/* Interfaces and alias receive addresses are stored in linked lists */
static csp_iface_t * interfaces = NULL;
static csp_alias_t * aliass = NULL;

int csp_iflist_is_within_subnet(uint16_t addr, csp_iface_t * ifc) {

Expand Down Expand Up @@ -101,6 +102,49 @@ csp_iface_t * csp_iflist_iterate(csp_iface_t * ifc) {

}

int csp_alias_add(csp_alias_t * addr) {

if (addr == NULL || addr->iface == NULL) {
return -1;
}

/* Register interface for L2 filtering, if interface supports */
if (addr->iface->add_alias) {
int result = addr->iface->add_alias(addr->iface->driver_data, addr->addr);
if (result < 0) {
return result;
}
}

/* Add to list */
addr->next = aliass;
aliass = addr;

return 0;
}

csp_alias_t * csp_alias_iterate(csp_alias_t * addr) {

if (addr == NULL) {
addr = aliass;
} else {
addr = addr->next;
}

return addr;
}

int csp_addr_is_alias(uint16_t addr) {

csp_alias_t * alias = NULL;
while ((alias = csp_alias_iterate(alias)) != NULL) {
if (addr == alias->addr) {
return 1;
}
}
return 0;
}

void csp_iflist_check_dfl(void) {

csp_iface_t * iface = csp_iflist_get_by_isdfl(NULL);
Expand Down Expand Up @@ -133,6 +177,18 @@ csp_iface_t * csp_iflist_get_by_addr(uint16_t addr) {

}

csp_iface_t * csp_iflist_get_by_broadcast(uint16_t addr) {

csp_iface_t * ifc = interfaces;
while (ifc) {
if (csp_id_is_broadcast(addr, ifc)) {
return ifc;
}
ifc = ifc->next;
}
return NULL;
}

csp_iface_t * csp_iflist_get_by_name(const char * name) {
csp_iface_t * ifc = interfaces;
while (ifc) {
Expand Down
6 changes: 6 additions & 0 deletions src/csp_rdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,12 @@ void csp_rdp_check_timeouts(csp_conn_t * conn) {

if (conn->rdp.state == RDP_OPEN) {

if (csp_rdp_time_after(time_now, conn->timestamp + conn->rdp.conn_timeout)) {
csp_conn_close(conn, CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT);
csp_bin_sem_post(&conn->rdp.tx_wait);
return;
}

/* Check if we have unacknowledged segments */
if (conn->rdp.delayed_acks) {
csp_rdp_check_ack(conn);
Expand Down
4 changes: 3 additions & 1 deletion src/csp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ int csp_route_work(void) {

/* The packet is to me, if the address matches that of any interface,
* or the address matches the broadcast address of the incoming interface */
int is_to_me = (csp_iflist_get_by_addr(packet->id.dst) != NULL || (csp_id_is_broadcast(packet->id.dst, input.iface)));
int is_to_me = ((csp_iflist_get_by_addr(packet->id.dst) != NULL ||
(csp_id_is_broadcast(packet->id.dst, input.iface))) ||
(csp_addr_is_alias(packet->id.dst)));

/* Deduplication */
if ((csp_conf.dedup == CSP_DEDUP_ALL) ||
Expand Down
4 changes: 2 additions & 2 deletions src/csp_rtable_cidr.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ int csp_rtable_set_internal(uint16_t address, uint16_t netmask, csp_iface_t * if
/* If not, create a new one */
if (!entry) {
entry = &rtable[rtable_inptr++];
if (rtable_inptr > CSP_RTABLE_SIZE) {
rtable_inptr = CSP_RTABLE_SIZE;
if (rtable_inptr >= CSP_RTABLE_SIZE) {
rtable_inptr = CSP_RTABLE_SIZE-1;
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/csp_rtable_stdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ static int csp_rtable_parse(const char * rtable, int dry_run) {
while ((str) && (strlen(str) > 1)) {
unsigned int address, via;
int netmask;
char name[15];
if (sscanf(str, "%u/%d %14s %u", &address, &netmask, name, &via) == 4) {
} else if (sscanf(str, "%u/%d %14s", &address, &netmask, name) == 3) {
char name[CSP_IFLIST_NAME_MAX] = {0};
if (sscanf(str, "%u/%d %9s %u", &address, &netmask, name, &via) == 4) {
} else if (sscanf(str, "%u/%d %9s", &address, &netmask, name) == 3) {
via = CSP_NO_VIA_ADDRESS;
} else if (sscanf(str, "%u %14s %u", &address, name, &via) == 3) {
} else if (sscanf(str, "%u %9s %u", &address, name, &via) == 3) {
netmask = csp_id_get_host_bits();
} else if (sscanf(str, "%u %14s", &address, name) == 2) {
} else if (sscanf(str, "%u %9s", &address, name) == 2) {
netmask = csp_id_get_host_bits();
via = CSP_NO_VIA_ADDRESS;
} else {
Expand Down
Loading
Loading