libsbp
v2.4.7
|
Send and receive messages using Swift Binary Protocol. More...
Data Structures | |
struct | sbp_msg_callbacks_node |
SBP callback node. More... | |
struct | sbp_state_t |
State structure for processing SBP messages. More... | |
Macros | |
#define | SBP_OK 0 |
Return value indicating success. More... | |
#define | SBP_OK_CALLBACK_EXECUTED 1 |
Return value indicating message decoded and callback executed by sbp_process. More... | |
#define | SBP_OK_CALLBACK_UNDEFINED 2 |
Return value indicating message decoded with no associated callback in sbp_process. More... | |
#define | SBP_CALLBACK_ERROR -1 |
Return value indicating an error with the callback (function defined). More... | |
#define | SBP_CRC_ERROR -2 |
Return value indicating a CRC error. More... | |
#define | SBP_SEND_ERROR -3 |
Return value indicating an error occured whilst sending an SBP message. More... | |
#define | SBP_NULL_ERROR -4 |
Return value indicating an error occured because an argument was NULL. More... | |
#define | SBP_WRITE_ERROR -5 |
Return value indicating an error occured in the write() operation. More... | |
#define | SBP_READ_ERROR -6 |
Return value indicating an error occured in the read() operation. More... | |
#define | SBP_SENDER_ID 0x42 |
Default sender ID. More... | |
#define | SBP_MAJOR_VERSION 2 |
Protocol major version. More... | |
#define | SBP_MINOR_VERSION 4 |
Protocol minor version. More... | |
#define | SBP_PATCH_VERSION 7 |
Protocol patch version. More... | |
Typedefs | |
typedef void(* | sbp_msg_callback_t) (u16 sender_id, u8 len, u8 msg[], void *context) |
SBP callback function prototype definition. More... | |
typedef struct sbp_msg_callbacks_node | sbp_msg_callbacks_node_t |
SBP callback node. More... | |
Enumerations | |
enum | { WAITING = 0, GET_TYPE, GET_SENDER, GET_LEN, GET_MSG, GET_CRC } |
Functions | |
s8 | sbp_register_callback (sbp_state_t *s, u16 msg_type, sbp_msg_callback_t cb, void *context, sbp_msg_callbacks_node_t *node) |
Register a callback for a message type. More... | |
s8 | sbp_remove_callback (sbp_state_t *s, sbp_msg_callbacks_node_t *node) |
Remove a registered callback. More... | |
void | sbp_clear_callbacks (sbp_state_t *s) |
Clear all registered callbacks. More... | |
void | sbp_state_init (sbp_state_t *s) |
Initialize an sbp_state_t struct before use. More... | |
void | sbp_state_set_io_context (sbp_state_t *s, void *context) |
Set a context to pass to all function pointer calls made by sbp functions This helper function sets a void* context pointer in sbp_state. More... | |
s8 | sbp_process (sbp_state_t *s, s32(*read)(u8 *buff, u32 n, void *context)) |
Read and process SBP messages. More... | |
s8 | sbp_process_payload (sbp_state_t *s, u16 sender_id, u16 msg_type, u8 msg_len, u8 payload[]) |
Directly process a SBP message. More... | |
s8 | sbp_send_message (sbp_state_t *s, u16 msg_type, u16 sender_id, u8 len, u8 *payload, s32(*write)(u8 *buff, u32 n, void *context)) |
Send SBP messages. More... | |
Send and receive messages using Swift Binary Protocol.
First setup a callback for the message you will be receiving. Our callback function must have type sbp_msg_callback_t, i.e. it must be of the form:
You must also statically allocate a sbp_msg_callbacks_node_t that will be used to keep track of the callback function. You do not need to initialize it as this will be done by sbp_register_callback().
Now register your callback function with the SBP library as follows:
where SBP_MY_MSG_TYPE
is the numerical identifier of your message type.
You must now call sbp_process() periodically whenever you have received SBP data to be processed, e.g. from the serial port. Remember sbp_process() may not use all available data so keep calling sbp_process() until all the received serial data has been consumed.
sbp_process() stores its internal state in an sbp_state_t struct which must be initialized by calling sbp_state_init() before its first use.
Here is an example based on reading from a typical UART interface:
If you're writing C++ code that wants to reference a pointer to an object in the my_read function, you can use the context set by calling sbp_state_set_io_context()
To send an SBP message simply call the sbp_send_message() function, providing a write
function that writes data to your output.
Often the data to be sent will simply be a struct cast to a u8
buffer. As a convenience you may want to define a macro that automatically includes your write function and calculates the size of the item to be sent.
#define SBP_CALLBACK_ERROR -1 |
#define SBP_NULL_ERROR -4 |
#define SBP_OK_CALLBACK_EXECUTED 1 |
#define SBP_OK_CALLBACK_UNDEFINED 2 |
#define SBP_READ_ERROR -6 |
#define SBP_SEND_ERROR -3 |
#define SBP_SENDER_ID 0x42 |
#define SBP_WRITE_ERROR -5 |
typedef struct sbp_msg_callbacks_node sbp_msg_callbacks_node_t |
SBP callback node.
Forms a linked list of callbacks.
anonymous enum |
void sbp_clear_callbacks | ( | sbp_state_t * | s | ) |
s8 sbp_process | ( | sbp_state_t * | s, |
s32(*)(u8 *buff, u32 n, void *context) | read | ||
) |
Read and process SBP messages.
Reads bytes from an input source using the provided read
function, decodes the SBP framing and performs a CRC check on the message.
When an SBP message is successfully received then the list of callbacks is searched for a callback corresponding to the received message type. If a callback is found then it is called with the ID of the sender, the message length and the message payload data buffer as arguments.
read
with n > 0 (aka it will attempt to always read something)The supplied read
function must have the prototype:
where n
is the number of bytes requested and buff
is the buffer into which to write the received data, and context
is the arbitrary pointer set by sbp_state_set_io_context
. The function should return the number of bytes successfully written into buff
which may be between 0 and n
inclusive, but must never be greater than n
.
Note that sbp_process
may not read all available bytes from the read
function so the caller should loop until all bytes available from the input source have been consumed.
s | State structure |
read | Function pointer to a function that reads n bytes from the input source into buff and returns the number of bytes successfully read. |
SBP_OK
(0) if successful but no complete message yet, SBP_OK_CALLBACK_EXECUTED
(1) if message decoded and callback executed, SBP_OK_CALLBACK_UNDEFINED
(2) if message decoded with no associated callback, and SBP_CRC_ERROR
(-2) if a CRC error has occurred. Thus can check for >0 to ensure good processing. Definition at line 308 of file sbp.c.
Directly process a SBP message.
If a SBP message has already been decoded (for example, from a binary stream or from a JSON log file) use this function to directly process it.
s | State structure |
sender_id | SBP message sender id |
msg_type | SBP message type |
msg_len | SBP message length |
payload | SBP message payload |
SBP_OK_CALLBACK_EXECUTED
(1) if message decoded and callback executed, SBP_OK_CALLBACK_UNDEFINED
(2) if message decoded with no associated callback. Definition at line 416 of file sbp.c.
s8 sbp_register_callback | ( | sbp_state_t * | s, |
u16 | msg_type, | ||
sbp_msg_callback_t | cb, | ||
void * | context, | ||
sbp_msg_callbacks_node_t * | node | ||
) |
Register a callback for a message type.
Register a callback that is called when a message with type msg_type is received.
msg_type | Message type associated with callback |
cb | Pointer to message callback function |
context | Pointer to context for callback function |
node | Statically allocated sbp_msg_callbacks_node_t struct |
SBP_OK
(0) if successful, SBP_CALLBACK_ERROR
if callback was already registered for that message type. s8 sbp_remove_callback | ( | sbp_state_t * | s, |
sbp_msg_callbacks_node_t * | node | ||
) |
Remove a registered callback.
node | sbp_msg_callbacks_node_t struct of callback to remove. |
SBP_OK
(0) if successful, SBP_CALLBACK_ERROR
if no callback was registered for that message type. s8 sbp_send_message | ( | sbp_state_t * | s, |
u16 | msg_type, | ||
u16 | sender_id, | ||
u8 | len, | ||
u8 * | payload, | ||
s32(*)(u8 *buff, u32 n, void *context) | write | ||
) |
Send SBP messages.
Takes an SBP message payload, type and sender ID then writes a message to the output stream using the supplied write
function with the correct framing and CRC.
The supplied write
function must have the prototype:
where n
is the number of bytes to be written and buff
is the buffer from which to read the data to be written, and context
is the arbitrary pointer set by sbp_state_set_io_context
. The function should return the number of bytes successfully written which may be between 0 and n
. Currently, if the number of bytes written is different from n
then sbp_send_message
will immediately return with an error.
Note that sbp_send_message
makes multiple calls to write and therefore if a write
call fails then this may result in a partial message being written to the output. This should be caught by the CRC check on the receiving end but will result in lost messages.
write | Function pointer to a function that writes n bytes from buff to the output stream and returns the number of bytes successfully written. |
SBP_OK
(0) if successful, SBP_WRITE_ERROR
if the message could not be sent or was only partially sent. Definition at line 459 of file sbp.c.
void sbp_state_init | ( | sbp_state_t * | s | ) |
Initialize an sbp_state_t struct before use.
This resets the entire state, including all callbacks. Remember to use this function to initialize the state before calling sbp_process() for the first time.
s | State structure |
Definition at line 246 of file sbp.c.
void sbp_state_set_io_context | ( | sbp_state_t * | s, |
void * | context | ||
) |
Set a context to pass to all function pointer calls made by sbp functions This helper function sets a void* context pointer in sbp_state.
Whenever sbp_process
calls the read
function pointer, it passes this context. Whenever sbp_send_message
calls the write
function pointer, it passes this context. This allows C++ code to get a pointer to an object inside these functions.