eive-obsw/gomspace/libcsp/include/csp/csp.h
2020-11-23 11:42:22 +01:00

546 lines
19 KiB
C

/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_H_
#define _CSP_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Includes */
#include <stdint.h>
#include <csp/csp_autoconfig.h>
/* CSP includes */
#include "csp_types.h"
#include "csp_platform.h"
#include "csp_error.h"
#include "csp_debug.h"
#include "csp_buffer.h"
#include "csp_rtable.h"
#include "csp_iflist.h"
/** csp_init
* Start up the can-space protocol
* @param my_node_address The CSP node address
*/
int csp_init(uint8_t my_node_address);
/** csp_set_address
* Set the systems own address
* @param addr The new address of the system
*/
void csp_set_address(uint8_t addr);
/** csp_get_address
* Get the systems own address
* @return The current address of the system
*/
uint8_t csp_get_address(void);
/** csp_set_hostname
* Set subsystem hostname.
* This function takes a pointer to a string, which should remain static
* @param hostname Hostname to set
*/
void csp_set_hostname(const char *hostname);
/** csp_get_hostname
* Get current subsystem hostname.
* @return Pointer to char array with current hostname.
*/
const char *csp_get_hostname(void);
/** csp_set_model
* Set subsystem model name.
* This function takes a pointer to a string, which should remain static
* @param model Model name to set
*/
void csp_set_model(const char *model);
/** csp_get_model
* Get current model name.
* @return Pointer to char array with current model name.
*/
const char *csp_get_model(void);
/** csp_set_revision
* Set subsystem revision. This can be used to override the CMP revision field.
* This function takes a pointer to a string, which should remain static
* @param revision Revision name to set
*/
void csp_set_revision(const char *revision);
/** csp_get_revision
* Get subsystem revision.
* @return Pointer to char array with software revision.
*/
const char *csp_get_revision(void);
/** csp_socket
* Create CSP socket endpoint
* @param opts Socket options
* @return Pointer to socket on success, NULL on failure
*/
csp_socket_t *csp_socket(uint32_t opts);
/**
* Wait for a new connection on a socket created by csp_socket
* @param socket Socket to accept connections on
* @param timeout use CSP_MAX_DELAY for infinite timeout
* @return Return pointer to csp_conn_t or NULL if timeout was reached
*/
csp_conn_t *csp_accept(csp_socket_t *socket, uint32_t timeout);
/**
* Read data from a connection
* This fuction uses the RX queue of a connection to receive a packet
* If no packet is available and a timeout has been specified
* The call will block.
* Do NOT call this from ISR
* @param conn pointer to connection
* @param timeout timeout in ms, use CSP_MAX_DELAY for infinite blocking time
* @return Returns pointer to csp_packet_t, which you MUST free yourself, either by calling csp_buffer_free() or reusing the buffer for a new csp_send.
*/
csp_packet_t *csp_read(csp_conn_t *conn, uint32_t timeout);
/**
* Send a packet on an already established connection
* @param conn pointer to connection
* @param packet pointer to packet,
* @param timeout a timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control.
* @return returns 1 if successful and 0 otherwise. you MUST free the frame yourself if the transmission was not successful.
*/
int csp_send(csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout);
/**
* Send a packet on an already established connection, and change the default priority of the connection
*
* @note When using this function, the priority of the connection will change. If you need to change it back
* use another call to csp_send_prio, or ensure that all packets sent on a given connection is using send_prio call.
*
* @param prio csp priority
* @param conn pointer to connection
* @param packet pointer to packet,
* @param timeout a timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control.
* @return returns 1 if successful and 0 otherwise. you MUST free the frame yourself if the transmission was not successful.
*/
int csp_send_prio(uint8_t prio, csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout);
/**
* Perform an entire request/reply transaction
* Copies both input buffer and reply to output buffeer.
* Also makes the connection and closes it again
* @param prio CSP Prio
* @param dest CSP Dest
* @param port CSP Port
* @param timeout timeout in ms
* @param outbuf pointer to outgoing data buffer
* @param outlen length of request to send
* @param inbuf pointer to incoming data buffer
* @param inlen length of expected reply, -1 for unknown size (note inbuf MUST be large enough)
* @return Return 1 or reply size if successful, 0 if error or incoming length does not match or -1 if timeout was reached
*/
int csp_transaction(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen);
/**
* Perform an entire request/reply transaction
* Copies both input buffer and reply to output buffeer.
* Also makes the connection and closes it again
* @param prio CSP Prio
* @param dest CSP Dest
* @param port CSP Port
* @param timeout timeout in ms
* @param outbuf pointer to outgoing data buffer
* @param outlen length of request to send
* @param inbuf pointer to incoming data buffer
* @param inlen length of expected reply, -1 for unknown size (note inbuf MUST be large enough)
* @param opts Connection options.
* @return Return 1 or reply size if successful, 0 if error or incoming length does not match or -1 if timeout was reached
*/
int csp_transaction2(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen, uint32_t opts);
/**
* Use an existing connection to perform a transaction,
* This is only possible if the next packet is on the same port and destination!
* @param conn pointer to connection structure
* @param timeout timeout in ms
* @param outbuf pointer to outgoing data buffer
* @param outlen length of request to send
* @param inbuf pointer to incoming data buffer
* @param inlen length of expected reply, -1 for unknown size (note inbuf MUST be large enough)
* @return
*/
int csp_transaction_persistent(csp_conn_t *conn, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen);
/**
* Read data from a connection-less server socket
* This fuction uses the socket directly to receive a frame
* If no packet is available and a timeout has been specified the call will block.
* Do NOT call this from ISR
* @return Returns pointer to csp_packet_t, which you MUST free yourself, either by calling csp_buffer_free() or reusing the buffer for a new csp_send.
*/
csp_packet_t *csp_recvfrom(csp_socket_t *socket, uint32_t timeout);
/**
* Send a packet without previously opening a connection
* @param prio CSP_PRIO_x
* @param dest destination node
* @param dport destination port
* @param src_port source port
* @param opts CSP_O_x
* @param packet pointer to packet
* @param timeout timeout used by interfaces with blocking send
* @return -1 if error (you must free packet), 0 if OK (you must discard pointer)
*/
int csp_sendto(uint8_t prio, uint8_t dest, uint8_t dport, uint8_t src_port, uint32_t opts, csp_packet_t *packet, uint32_t timeout);
/**
* Send a packet as a direct reply to the source of an incoming packet,
* but still without holding an entire connection
* @param request_packet pointer to packet to reply to
* @param reply_packet actual reply data
* @param opts CSP_O_x
* @param timeout timeout used by interfaces with blocking send
* @return -1 if error (you must free packet), 0 if OK (you must discard pointer)
*/
int csp_sendto_reply(csp_packet_t * request_packet, csp_packet_t * reply_packet, uint32_t opts, uint32_t timeout);
/** csp_connect
* Used to establish outgoing connections
* This function searches the port table for free slots and finds an unused
* connection from the connection pool
* There is no handshake in the CSP protocol
* @param prio Connection priority.
* @param dest Destination address.
* @param dport Destination port.
* @param timeout Timeout in ms.
* @param opts Connection options.
* @return a pointer to a new connection or NULL
*/
csp_conn_t *csp_connect(uint8_t prio, uint8_t dest, uint8_t dport, uint32_t timeout, uint32_t opts);
/** csp_close
* Closes a given connection and frees buffers used.
* @param conn pointer to connection structure
* @return CSP_ERR_NONE if connection was closed. Otherwise, an err code is returned.
*/
int csp_close(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return destination port of an incoming connection
*/
int csp_conn_dport(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return source port of an incoming connection
*/
int csp_conn_sport(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return destination address of an incoming connection
*/
int csp_conn_dst(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return source address of an incoming connection
*/
int csp_conn_src(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return flags field of an incoming connection
*/
int csp_conn_flags(csp_conn_t *conn);
/**
* Set socket to listen for incoming connections
* @param socket Socket to enable listening on
* @param conn_queue_length Lenght of backlog connection queue
* @return 0 on success, -1 on error.
*/
int csp_listen(csp_socket_t *socket, size_t conn_queue_length);
/**
* Bind port to socket
* @param socket Socket to bind port to
* @param port Port number to bind
* @return 0 on success, -1 on error.
*/
int csp_bind(csp_socket_t *socket, uint8_t port);
/**
* Start the router task.
* @param task_stack_size The number of portStackType to allocate. This only affects FreeRTOS systems.
* @param priority The OS task priority of the router
*/
int csp_route_start_task(unsigned int task_stack_size, unsigned int priority);
/**
* Call the router worker function manually (without the router task)
* This must be run inside a loop or called periodically for the csp router to work.
* Use this function instead of calling and starting the router task.
* @param timeout max blocking time
* @return -1 if no packet was processed, 0 otherwise
*/
int csp_route_work(uint32_t timeout);
/**
* Start the bridge task.
* @param task_stack_size The number of portStackType to allocate. This only affects FreeRTOS systems.
* @param priority The OS task priority of the router
* @param _if_a pointer to first side
* @param _if_b pointer to second side
* @return CSP_ERR type
*/
int csp_bridge_start(unsigned int task_stack_size, unsigned int task_priority, csp_iface_t * _if_a, csp_iface_t * _if_b);
/**
* Enable promiscuous mode packet queue
* This function is used to enable promiscuous mode for the router.
* If enabled, a copy of all incoming packets are placed in a queue
* that can be read with csp_promisc_get(). Not all interface drivers
* support promiscuous mode.
*
* @param buf_size Size of buffer for incoming packets
*/
int csp_promisc_enable(unsigned int buf_size);
/**
* Disable promiscuous mode.
* If the queue was initialised prior to this, it can be re-enabled
* by calling promisc_enable(0)
*/
void csp_promisc_disable(void);
/**
* Get packet from promiscuous mode packet queue
* Returns the first packet from the promiscuous mode packet queue.
* The queue is FIFO, so the returned packet is the oldest one
* in the queue.
*
* @param timeout Timeout in ms to wait for a new packet
*/
csp_packet_t *csp_promisc_read(uint32_t timeout);
/**
* Send multiple packets using the simple fragmentation protocol
* CSP will add total size and offset to all packets
* This can be read by the client using the csp_sfp_recv, if the CSP_FFRAG flag is set
* @param conn pointer to connection
* @param data pointer to data to send
* @param totalsize size of data to send
* @param mtu maximum transfer unit
* @param timeout timeout in ms to wait for csp_send()
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_send(csp_conn_t * conn, const void * data, int totalsize, int mtu, uint32_t timeout);
/**
* Same as csp_sfp_send but with option to supply your own memcpy function.
* This is usefull if you wish to send data stored in flash memory or another location
* @param conn pointer to connection
* @param data pointer to data to send
* @param totalsize size of data to send
* @param mtu maximum transfer unit
* @param timeout timeout in ms to wait for csp_send()
* @param memcpyfcn, pointer to memcpy function
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_send_own_memcpy(csp_conn_t * conn, const void * data, int totalsize, int mtu, uint32_t timeout, void * (*memcpyfcn)(void *, const void *, size_t));
/**
* This is the counterpart to the csp_sfp_send function
* @param conn pointer to active conn, on which you expect to receive sfp packed data
* @param dataout pointer to NULL pointer, whill be overwritten with malloc pointer
* @param datasize actual size of received data
* @param timeout timeout in ms to wait for csp_recv()
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_recv(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout);
/**
* This is the counterpart to the csp_sfp_send function
* @param conn pointer to active conn, on which you expect to receive sfp packed data
* @param dataout pointer to NULL pointer, whill be overwritten with malloc pointer
* @param datasize actual size of received data
* @param timeout timeout in ms to wait for csp_recv()
* @param first_packet This is a pointer to the first SFP packet (previously received with csp_read)
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_recv_fp(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout, csp_packet_t * first_packet);
/**
* If the given packet is a service-request (that is uses one of the csp service ports)
* it will be handled according to the CSP service handler.
* This function will either use the packet buffer or delete it,
* so this function is typically called in the last "default" clause of
* a switch/case statement in a csp_listener task.
* In order to listen to csp service ports, bind your listener to the CSP_ANY port.
* This function may only be called from task context.
* @param conn Pointer to the new connection
* @param packet Pointer to the first packet, obtained by using csp_read()
*/
void csp_service_handler(csp_conn_t *conn, csp_packet_t *packet);
/**
* Send a single ping/echo packet
* @param node node id
* @param timeout timeout in ms
* @param size size of packet to transmit
* @param conn_options csp connection options
* @return >0 = Echo time in ms, -1 = ERR
*/
int csp_ping(uint8_t node, uint32_t timeout, unsigned int size, uint8_t conn_options);
/**
* Send a single ping/echo packet without waiting for reply
* @param node node id
*/
void csp_ping_noreply(uint8_t node);
/**
* Request process list.
* @note This is only available for FreeRTOS systems
* @param node node id
* @param timeout timeout in ms
*/
void csp_ps(uint8_t node, uint32_t timeout);
/**
* Request amount of free memory
* @param node node id
* @param timeout timeout in ms
*/
void csp_memfree(uint8_t node, uint32_t timeout);
/**
* Request number of free buffer elements
* @param node node id
* @param timeout timeout in ms
*/
void csp_buf_free(uint8_t node, uint32_t timeout);
/**
* Reboot subsystem
* @param node node id
*/
void csp_reboot(uint8_t node);
/**
* Shutdown subsystem
* @param node node id
*/
void csp_shutdown(uint8_t node);
/**
* Request subsystem uptime
* @param node node id
* @param timeout timeout in ms
*/
void csp_uptime(uint8_t node, uint32_t timeout);
/**
* Set RDP options
* @param window_size Window size
* @param conn_timeout_ms Connection timeout in ms
* @param packet_timeout_ms Packet timeout in ms
* @param delayed_acks Enable/disable delayed acknowledgements
* @param ack_timeout Acknowledgement timeout when delayed ACKs is enabled
* @param ack_delay_count Send acknowledgement for every ack_delay_count packets
*/
void csp_rdp_set_opt(unsigned int window_size, unsigned int conn_timeout_ms,
unsigned int packet_timeout_ms, unsigned int delayed_acks,
unsigned int ack_timeout, unsigned int ack_delay_count);
/**
* Get RDP options
* @param window_size Window size
* @param conn_timeout_ms Connection timeout in ms
* @param packet_timeout_ms Packet timeout in ms
* @param delayed_acks Enable/disable delayed acknowledgements
* @param ack_timeout Acknowledgement timeout when delayed ACKs is enabled
* @param ack_delay_count Send acknowledgement for every ack_delay_count packets
*/
void csp_rdp_get_opt(unsigned int *window_size, unsigned int *conn_timeout_ms,
unsigned int *packet_timeout_ms, unsigned int *delayed_acks,
unsigned int *ack_timeout, unsigned int *ack_delay_count);
/**
* Set XTEA key
* @param key Pointer to key array
* @param keylen Length of key
* @return 0 if key was successfully set, -1 otherwise
*/
int csp_xtea_set_key(char *key, uint32_t keylen);
/**
* Set HMAC key
* @param key Pointer to key array
* @param keylen Length of key
* @return 0 if key was successfully set, -1 otherwise
*/
int csp_hmac_set_key(char *key, uint32_t keylen);
/**
* Print connection table
*/
void csp_conn_print_table(void);
int csp_conn_print_table_str(char * str_buf, int str_size);
/**
* Print buffer usage table
*/
void csp_buffer_print_table(void);
/**
* Hex dump to stdout
*/
void csp_hex_dump(const char *desc, void *addr, int len);
#ifdef __AVR__
typedef uint32_t csp_memptr_t;
#else
typedef void * csp_memptr_t;
#endif
typedef csp_memptr_t (*csp_memcpy_fnc_t)(csp_memptr_t, const csp_memptr_t, size_t);
void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc);
/**
* Set csp_debug hook function
* @param f Hook function
*/
#include <stdarg.h>
typedef void (*csp_debug_hook_func_t)(csp_debug_level_t level, const char *format, va_list args);
void csp_debug_hook_set(csp_debug_hook_func_t f);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_H_