1*479e2648SJackson Cooper-Driver /* 2*479e2648SJackson Cooper-Driver * Copyright (c) 2026, Arm Limited. All rights reserved. 3*479e2648SJackson Cooper-Driver * 4*479e2648SJackson Cooper-Driver * SPDX-License-Identifier: BSD-3-Clause 5*479e2648SJackson Cooper-Driver * 6*479e2648SJackson Cooper-Driver */ 7*479e2648SJackson Cooper-Driver 8*479e2648SJackson Cooper-Driver #ifndef __SFCP_H__ 9*479e2648SJackson Cooper-Driver #define __SFCP_H__ 10*479e2648SJackson Cooper-Driver 11*479e2648SJackson Cooper-Driver #include <stdbool.h> 12*479e2648SJackson Cooper-Driver #include <stddef.h> 13*479e2648SJackson Cooper-Driver #include <stdint.h> 14*479e2648SJackson Cooper-Driver 15*479e2648SJackson Cooper-Driver #include <drivers/arm/sfcp_link_defs.h> 16*479e2648SJackson Cooper-Driver 17*479e2648SJackson Cooper-Driver #ifdef __cplusplus 18*479e2648SJackson Cooper-Driver extern "C" { 19*479e2648SJackson Cooper-Driver #endif 20*479e2648SJackson Cooper-Driver 21*479e2648SJackson Cooper-Driver /** 22*479e2648SJackson Cooper-Driver * \brief Minimum buffer size (in bytes) required for any SFCP packet. 23*479e2648SJackson Cooper-Driver * 24*479e2648SJackson Cooper-Driver * \details 25*479e2648SJackson Cooper-Driver * This constant defines the smallest valid buffer size that can be passed to 26*479e2648SJackson Cooper-Driver * SFCP send/receive/init functions. It accounts for the packet header, 27*479e2648SJackson Cooper-Driver * required metadata fields, and any alignment requirements, but does not 28*479e2648SJackson Cooper-Driver * include any additional payload space. 29*479e2648SJackson Cooper-Driver * 30*479e2648SJackson Cooper-Driver * Buffers smaller than this size are guaranteed to be rejected with 31*479e2648SJackson Cooper-Driver * ::SFCP_ERROR_BUFFER_TOO_SMALL. 32*479e2648SJackson Cooper-Driver * 33*479e2648SJackson Cooper-Driver * This macro is intended for compile-time allocation checks or for ensuring 34*479e2648SJackson Cooper-Driver * that dynamically allocated buffers meet the protocol's minimum size 35*479e2648SJackson Cooper-Driver * requirements before calling SFCP APIs. 36*479e2648SJackson Cooper-Driver */ 37*479e2648SJackson Cooper-Driver #define SFCP_BUFFER_MINIMUM_SIZE (40) 38*479e2648SJackson Cooper-Driver 39*479e2648SJackson Cooper-Driver /** 40*479e2648SJackson Cooper-Driver * \brief Library return codes for the SFCP API. 41*479e2648SJackson Cooper-Driver * 42*479e2648SJackson Cooper-Driver * Notes: 43*479e2648SJackson Cooper-Driver * - Polling receives SHOULD use the *_NO_MSG_AVAILABLE / *_NO_REPLY_AVAILABLE codes 44*479e2648SJackson Cooper-Driver * when nothing is ready to read (non-fatal “no data” condition). 45*479e2648SJackson Cooper-Driver * - If a provided buffer is too small to hold the packet header + metadata, 46*479e2648SJackson Cooper-Driver * the call MUST return SFCP_ERROR_BUFFER_TOO_SMALL. 47*479e2648SJackson Cooper-Driver */ 48*479e2648SJackson Cooper-Driver enum sfcp_error_t { 49*479e2648SJackson Cooper-Driver SFCP_ERROR_SUCCESS = 0, 50*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_POINTER, 51*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_SENDER_ID, 52*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_PACKET, 53*479e2648SJackson Cooper-Driver SFCP_ERROR_MESSAGE_TOO_SMALL, 54*479e2648SJackson Cooper-Driver SFCP_ERROR_BUFFER_TOO_SMALL, 55*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_LEGACY_FORMAT_CONFIGURATION, 56*479e2648SJackson Cooper-Driver SFCP_ERROR_PAYLOAD_TOO_LARGE, 57*479e2648SJackson Cooper-Driver SFCP_ERROR_CRYPTOGRAPHY_NOT_SUPPORTED, 58*479e2648SJackson Cooper-Driver SFCP_ERROR_TRUSTED_SUBNET_MUST_BE_MANUALLY_SELECTED, 59*479e2648SJackson Cooper-Driver SFCP_ERROR_PAYLOAD_INVALID_ALIGNMENT, 60*479e2648SJackson Cooper-Driver SFCP_ERROR_ENCRYPTION_FAILED, 61*479e2648SJackson Cooper-Driver SFCP_ERROR_DECRYPTION_FAILED, 62*479e2648SJackson Cooper-Driver SFCP_ERROR_GENERATE_IV_FAILED, 63*479e2648SJackson Cooper-Driver SFCP_ERROR_GENERATE_SESSION_KEY_SEED_FAILED, 64*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_TRUSTED_SUBNET_ID, 65*479e2648SJackson Cooper-Driver SFCP_ERROR_TRUSTED_SUBNET_ALREADY_REGISTERED, 66*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_TRUSTED_SUBNET_NODE_ID, 67*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_TRUSTED_SUBNET_NODE_AMOUNT, 68*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_REPLY, 69*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_MSG, 70*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_NODE, 71*479e2648SJackson Cooper-Driver SFCP_ERROR_NO_MSG_AVAILABLE, 72*479e2648SJackson Cooper-Driver SFCP_ERROR_NO_REPLY_AVAILABLE, 73*479e2648SJackson Cooper-Driver SFCP_ERROR_SEND_MSG_AGAIN, 74*479e2648SJackson Cooper-Driver SFCP_ERROR_SEND_MSG_BUS_BUSY, 75*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_PROTOCOL_VERSION, 76*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_APPLICATION_ID, 77*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_CLIENT_ID, 78*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_CRYPTO_MODE, 79*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_MSG_TYPE, 80*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_SEQUENCE_NUMBER, 81*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_PACKET_SIZE, 82*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDLER_TABLE_FULL, 83*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_BUFFER_HANDLE, 84*479e2648SJackson Cooper-Driver SFCP_ERROR_INVALID_TRUSTED_SUBNET_STATE, 85*479e2648SJackson Cooper-Driver SFCP_ERROR_INTERNAL_HANDSHAKE_FAILURE, 86*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_GENERATE_RANDOM_FAILURE, 87*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_HASH_FAILURE, 88*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_HASH_ALG_UNSUPPORTED, 89*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_SETUP_SESSION_KEY_FAILURE, 90*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_REKEY_SESSION_KEY_FAILURE, 91*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_INVALIDATE_SESSION_KEY_FAILURE, 92*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_INVALID_RECEIVED_IV, 93*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_INVALID_RE_KEY_MSG, 94*479e2648SJackson Cooper-Driver SFCP_ERROR_HANDSHAKE_INVALID_MUTUAL_AUTH_MSG, 95*479e2648SJackson Cooper-Driver SFCP_ERROR_ALLOCATE_BUFFER_TOO_LARGE, 96*479e2648SJackson Cooper-Driver SFCP_ERROR_ALLOCATE_BUFFER_FAILED, 97*479e2648SJackson Cooper-Driver SFCP_ERROR_POP_BUFFER_FAILED, 98*479e2648SJackson Cooper-Driver SFCP_ERROR_MSG_ALREADY_RECEIVED, 99*479e2648SJackson Cooper-Driver SFCP_ERROR_MSG_OUT_OF_ORDER_TEMPORARY_FAILURE, 100*479e2648SJackson Cooper-Driver SFCP_ERROR_PROTOCOL_ERROR, 101*479e2648SJackson Cooper-Driver SFCP_ERROR_SEND_PACKET_BUS_BUSY, 102*479e2648SJackson Cooper-Driver SFCP_ERROR_HAL_ERROR_BASE, 103*479e2648SJackson Cooper-Driver SFCP_ERROR_HAL_ERROR_MAX = SFCP_ERROR_HAL_ERROR_BASE + 0x100, 104*479e2648SJackson Cooper-Driver SFCP_ERROR_FORCE_UINT32T_MAX = UINT32_MAX, 105*479e2648SJackson Cooper-Driver }; 106*479e2648SJackson Cooper-Driver 107*479e2648SJackson Cooper-Driver struct sfcp_packet_t; 108*479e2648SJackson Cooper-Driver 109*479e2648SJackson Cooper-Driver /** 110*479e2648SJackson Cooper-Driver * \brief Metadata captured at send time to match a future reply. 111*479e2648SJackson Cooper-Driver * 112*479e2648SJackson Cooper-Driver * \details 113*479e2648SJackson Cooper-Driver * The sender MUST NOT reuse a sequence number until the reply for the message 114*479e2648SJackson Cooper-Driver * using that sequence number has been received. If the ID extension is used, the 115*479e2648SJackson Cooper-Driver * (message_id, client_id) pair MUST remain unique among in-flight messages. 116*479e2648SJackson Cooper-Driver * If a timeout-retry mechanism is used, the sender MUST increment sequence numbers 117*479e2648SJackson Cooper-Driver * between messages and keep metadata for all outstanding messages to handle delayed 118*479e2648SJackson Cooper-Driver * replies. 119*479e2648SJackson Cooper-Driver */ 120*479e2648SJackson Cooper-Driver struct sfcp_reply_metadata_t { 121*479e2648SJackson Cooper-Driver sfcp_node_id_t receiver; /**< Intended receiver node ID. */ 122*479e2648SJackson Cooper-Driver bool uses_cryptography; /**< Whether crypto/auth is used for this exchange. 123*479e2648SJackson Cooper-Driver Replies MUST mirror this bit (except error replies, 124*479e2648SJackson Cooper-Driver which are never encrypted). */ 125*479e2648SJackson Cooper-Driver uint16_t client_id; /**< Client ID (0 if ID extension not used). */ 126*479e2648SJackson Cooper-Driver uint16_t application_id; /**< Application ID (0 if ID extension not used). */ 127*479e2648SJackson Cooper-Driver uint8_t message_id; /**< Message ID for matching. */ 128*479e2648SJackson Cooper-Driver uint8_t trusted_subnet_id; /**< Trusted subnet ID (only if uses_cryptography). */ 129*479e2648SJackson Cooper-Driver }; 130*479e2648SJackson Cooper-Driver 131*479e2648SJackson Cooper-Driver /** 132*479e2648SJackson Cooper-Driver * \brief Metadata captured at receive time to initialize a reply. 133*479e2648SJackson Cooper-Driver * 134*479e2648SJackson Cooper-Driver * \details 135*479e2648SJackson Cooper-Driver * A reply MUST use the same client ID and application ID as the original message, 136*479e2648SJackson Cooper-Driver * so it routes back to the correct caller/handler. 137*479e2648SJackson Cooper-Driver * The reply MUST also mirror the message’s uses_cryptography bit (except 138*479e2648SJackson Cooper-Driver * for protocol error replies, which cannot be encrypted). 139*479e2648SJackson Cooper-Driver */ 140*479e2648SJackson Cooper-Driver struct sfcp_msg_metadata_t { 141*479e2648SJackson Cooper-Driver sfcp_node_id_t 142*479e2648SJackson Cooper-Driver sender; /**< Original sender node ID (now the reply receiver). */ 143*479e2648SJackson Cooper-Driver bool uses_cryptography; /**< Whether the original message used crypto/auth. */ 144*479e2648SJackson Cooper-Driver uint16_t client_id; /**< Client ID from the original message (or 0). */ 145*479e2648SJackson Cooper-Driver uint16_t application_id; /**< Application ID from the original message (or 0). */ 146*479e2648SJackson Cooper-Driver uint8_t message_id; /**< Message ID from the original message. */ 147*479e2648SJackson Cooper-Driver uint8_t trusted_subnet_id; /**< Trusted subnet ID from the original message. */ 148*479e2648SJackson Cooper-Driver }; 149*479e2648SJackson Cooper-Driver 150*479e2648SJackson Cooper-Driver /** 151*479e2648SJackson Cooper-Driver * \brief Opaque handle for an entry in the internal message/reply buffer. 152*479e2648SJackson Cooper-Driver * 153*479e2648SJackson Cooper-Driver * \details 154*479e2648SJackson Cooper-Driver * A value of this type is passed to handler callbacks and later used with the 155*479e2648SJackson Cooper-Driver * *_pop_* functions to retrieve the corresponding packet from the internal 156*479e2648SJackson Cooper-Driver * buffer. The concrete encoding is implementation-defined. 157*479e2648SJackson Cooper-Driver */ 158*479e2648SJackson Cooper-Driver typedef uint32_t sfcp_buffer_handle_t; 159*479e2648SJackson Cooper-Driver 160*479e2648SJackson Cooper-Driver /** 161*479e2648SJackson Cooper-Driver * \brief Prototype for asynchronous handler functions (message or reply). 162*479e2648SJackson Cooper-Driver * 163*479e2648SJackson Cooper-Driver * \details 164*479e2648SJackson Cooper-Driver * The handler is invoked from the IRQ/deferred context with a buffer handle. 165*479e2648SJackson Cooper-Driver * The handler typically enqueues the handle and returns quickly; later, the 166*479e2648SJackson Cooper-Driver * consumer calls the appropriate *_pop_* routine to copy data out. 167*479e2648SJackson Cooper-Driver * 168*479e2648SJackson Cooper-Driver * \param[in] buffer_handle Handle for the buffered packet to process. 169*479e2648SJackson Cooper-Driver * 170*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS if the handle was accepted/queued; an error 171*479e2648SJackson Cooper-Driver * code otherwise. 172*479e2648SJackson Cooper-Driver */ 173*479e2648SJackson Cooper-Driver typedef enum sfcp_error_t (*sfcp_handler_t)(sfcp_buffer_handle_t buffer_handle); 174*479e2648SJackson Cooper-Driver 175*479e2648SJackson Cooper-Driver /** 176*479e2648SJackson Cooper-Driver * \brief Initializes the RSE communications layer. 177*479e2648SJackson Cooper-Driver * 178*479e2648SJackson Cooper-Driver * \details 179*479e2648SJackson Cooper-Driver * Initializes the transport/link integration used by the SFCP library. 180*479e2648SJackson Cooper-Driver * 181*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; otherwise a translated HAL error. 182*479e2648SJackson Cooper-Driver */ 183*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_init(void); 184*479e2648SJackson Cooper-Driver 185*479e2648SJackson Cooper-Driver /** 186*479e2648SJackson Cooper-Driver * \brief Prepare a message packet and payload buffer for sending. 187*479e2648SJackson Cooper-Driver * 188*479e2648SJackson Cooper-Driver * \param[in] buf Caller-provided buffer that will hold the entire packet 189*479e2648SJackson Cooper-Driver * (header + optional ID/crypto metadata + payload). 190*479e2648SJackson Cooper-Driver * \param[in] buf_size Size of \p buf. 191*479e2648SJackson Cooper-Driver * \param[in] receiver Destination node ID. 192*479e2648SJackson Cooper-Driver * \param[in] application_id Application ID at the receiver (0 means the receiver node itself). 193*479e2648SJackson Cooper-Driver * \param[in] client_id Client ID on behalf of which the sender is acting (0 means the sender node). 194*479e2648SJackson Cooper-Driver * \param[in] needs_reply If true, the packet type is MSG_NEEDS_REPLY; otherwise MSG_NO_REPLY. 195*479e2648SJackson Cooper-Driver * For MSG_NO_REPLY, the receiver MUST NOT send any reply. 196*479e2648SJackson Cooper-Driver * \param[in] manually_specify_ts_id If true, use the provided trusted_subnet_id; otherwise auto-select. 197*479e2648SJackson Cooper-Driver * \param[in] trusted_subnet_id Trusted subnet ID to use (only if manually_specify_ts_id is true). 198*479e2648SJackson Cooper-Driver * \param[out] payload Pointer within \p buf where the caller writes plaintext payload. 199*479e2648SJackson Cooper-Driver * \param[out] payload_len Capacity of the payload area (bytes). Caller MUST NOT exceed this. 200*479e2648SJackson Cooper-Driver * \param[out] msg Pointer to the prepared packet structure within \p buf. 201*479e2648SJackson Cooper-Driver * \param[out] msg_size Total packet size (header + metadata + payload capacity) to pass to send. 202*479e2648SJackson Cooper-Driver * \param[out] metadata Populated with values needed to match a future reply. 203*479e2648SJackson Cooper-Driver * 204*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 205*479e2648SJackson Cooper-Driver * SFCP_ERROR_CRYPTOGRAPHY_NOT_SUPPORTED if crypto is requested but unsupported; 206*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_BUFFER / SFCP_ERROR_BUFFER_TOO_SMALL on buffer issues; 207*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_NODE for invalid destination. 208*479e2648SJackson Cooper-Driver */ 209*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_init_msg(uint8_t *buf, size_t buf_size, 210*479e2648SJackson Cooper-Driver sfcp_node_id_t receiver, 211*479e2648SJackson Cooper-Driver uint16_t application_id, uint16_t client_id, 212*479e2648SJackson Cooper-Driver bool needs_reply, bool manually_specify_ts_id, 213*479e2648SJackson Cooper-Driver uint8_t trusted_subnet_id, uint8_t **payload, 214*479e2648SJackson Cooper-Driver size_t *payload_len, struct sfcp_packet_t **msg, 215*479e2648SJackson Cooper-Driver size_t *msg_size, 216*479e2648SJackson Cooper-Driver struct sfcp_reply_metadata_t *metadata); 217*479e2648SJackson Cooper-Driver 218*479e2648SJackson Cooper-Driver /** 219*479e2648SJackson Cooper-Driver * \brief Transmit a prepared message packet. 220*479e2648SJackson Cooper-Driver * 221*479e2648SJackson Cooper-Driver * \param[in] msg Pointer to packet prepared by sfcp_init_msg (unaltered). 222*479e2648SJackson Cooper-Driver * \param[in] msg_size Total size of the packet buffer. 223*479e2648SJackson Cooper-Driver * \param[in] payload_size Number of bytes of the payload area actually used. 224*479e2648SJackson Cooper-Driver * 225*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 226*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_PACKET / SFCP_ERROR_MESSAGE_TOO_SMALL / 227*479e2648SJackson Cooper-Driver * SFCP_ERROR_PAYLOAD_TOO_LARGE if the packet is malformed or sizes mismatch; 228*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_NODE if routing fails; 229*479e2648SJackson Cooper-Driver * a translated HAL error on transport failure. 230*479e2648SJackson Cooper-Driver * 231*479e2648SJackson Cooper-Driver * \note The application supplies plaintext in the payload; the library performs any required 232*479e2648SJackson Cooper-Driver * encryption/authentication transparently before sending. 233*479e2648SJackson Cooper-Driver */ 234*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_send_msg(struct sfcp_packet_t *msg, size_t msg_size, 235*479e2648SJackson Cooper-Driver size_t payload_size); 236*479e2648SJackson Cooper-Driver 237*479e2648SJackson Cooper-Driver /** 238*479e2648SJackson Cooper-Driver * \brief Prepare a reply packet and payload buffer corresponding to a received message. 239*479e2648SJackson Cooper-Driver * 240*479e2648SJackson Cooper-Driver * \param[in] buf Caller-provided buffer for the entire reply packet. 241*479e2648SJackson Cooper-Driver * \param[in] buf_size Size of \p buf. 242*479e2648SJackson Cooper-Driver * \param[in] metadata Metadata captured when the message was received; the reply will: 243*479e2648SJackson Cooper-Driver * - mirror uses_cryptography (except protocol error replies, 244*479e2648SJackson Cooper-Driver * which cannot be encrypted), and 245*479e2648SJackson Cooper-Driver * - use the same client_id, application_id, and message_id. 246*479e2648SJackson Cooper-Driver * \param[out] payload Pointer within \p buf where the caller writes the plaintext reply payload. 247*479e2648SJackson Cooper-Driver * \param[out] payload_len Capacity of the reply payload area (bytes). 248*479e2648SJackson Cooper-Driver * \param[out] reply Pointer to the prepared reply packet within \p buf. 249*479e2648SJackson Cooper-Driver * \param[out] reply_size Total packet size to pass to sfcp_send_reply. 250*479e2648SJackson Cooper-Driver * 251*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; *_BUFFER_TOO_SMALL if \p buf is insufficient; or a 252*479e2648SJackson Cooper-Driver * translated HAL error if local node ID cannot be obtained. 253*479e2648SJackson Cooper-Driver */ 254*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_init_reply(uint8_t *buf, size_t buf_size, 255*479e2648SJackson Cooper-Driver struct sfcp_msg_metadata_t metadata, 256*479e2648SJackson Cooper-Driver uint8_t **payload, size_t *payload_len, 257*479e2648SJackson Cooper-Driver struct sfcp_packet_t **reply, 258*479e2648SJackson Cooper-Driver size_t *reply_size); 259*479e2648SJackson Cooper-Driver 260*479e2648SJackson Cooper-Driver /** 261*479e2648SJackson Cooper-Driver * \brief Transmit a prepared reply packet. 262*479e2648SJackson Cooper-Driver * 263*479e2648SJackson Cooper-Driver * \param[in] reply Pointer to packet prepared by sfcp_init_reply (unaltered). 264*479e2648SJackson Cooper-Driver * \param[in] reply_size Total size of the packet buffer. 265*479e2648SJackson Cooper-Driver * \param[in] payload_size Number of bytes of the payload area actually used. 266*479e2648SJackson Cooper-Driver * 267*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; the same validation/routing/transport errors as send_msg. 268*479e2648SJackson Cooper-Driver * 269*479e2648SJackson Cooper-Driver * \note Normal replies MUST mirror the message’s uses_cryptography bit. 270*479e2648SJackson Cooper-Driver * Protocol error replies are never encrypted. 271*479e2648SJackson Cooper-Driver */ 272*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_send_reply(struct sfcp_packet_t *reply, 273*479e2648SJackson Cooper-Driver size_t reply_size, size_t payload_size); 274*479e2648SJackson Cooper-Driver 275*479e2648SJackson Cooper-Driver /** 276*479e2648SJackson Cooper-Driver * \brief Receive a message (polling mode). 277*479e2648SJackson Cooper-Driver * 278*479e2648SJackson Cooper-Driver * \details 279*479e2648SJackson Cooper-Driver * Retrieves the next available message destined for \p sender (by route), validates it, 280*479e2648SJackson Cooper-Driver * and exposes the plaintext payload pointer and capacity. If nothing is available, returns 281*479e2648SJackson Cooper-Driver * SFCP_ERROR_NO_MSG_AVAILABLE (non-fatal). 282*479e2648SJackson Cooper-Driver * 283*479e2648SJackson Cooper-Driver * Validation rules enforced include: 284*479e2648SJackson Cooper-Driver * - Packet type MUST be MSG_NEEDS_REPLY or MSG_NO_REPLY. 285*479e2648SJackson Cooper-Driver * - Protocol version MUST equal 0b10. 286*479e2648SJackson Cooper-Driver * - If ID extension not present, receiver MUST treat client_id/application_id as 0; 287*479e2648SJackson Cooper-Driver * otherwise, they MUST be read from their fields. 288*479e2648SJackson Cooper-Driver * - Receiver MUST route handling based on application_id; if out of range, return 289*479e2648SJackson Cooper-Driver * INVALID_APPLICATION_ID (sender of MSG_NEEDS_REPLY will receive an error reply). 290*479e2648SJackson Cooper-Driver * - If message crypto setting doesn’t match the expected uses_cryptography, return INVALID_CRYPTO_MODE. 291*479e2648SJackson Cooper-Driver * - For MSG_NO_REPLY, the receiver MUST NOT send a reply even on failure. 292*479e2648SJackson Cooper-Driver * 293*479e2648SJackson Cooper-Driver * \param[in] buf Buffer to receive the packet. 294*479e2648SJackson Cooper-Driver * \param[in] buf_size Size of \p buf. 295*479e2648SJackson Cooper-Driver * \param[in] any_sender Message can come from any known sender, if set \p sender must be 0 296*479e2648SJackson Cooper-Driver * \param[in] sender Expected sender node ID. 297*479e2648SJackson Cooper-Driver * \param[in] application_id Application ID this receiver instance handles (0 for node handler). 298*479e2648SJackson Cooper-Driver * \param[out] client_id Client ID extracted from the message (0 if no ID extension). 299*479e2648SJackson Cooper-Driver * \param[out] payload Pointer within \p buf to the plaintext payload. 300*479e2648SJackson Cooper-Driver * \param[out] payload_len Capacity of \p payload (bytes). 301*479e2648SJackson Cooper-Driver * \param[out] metadata Set to values needed to initialize a reply. 302*479e2648SJackson Cooper-Driver * 303*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 304*479e2648SJackson Cooper-Driver * SFCP_ERROR_NO_MSG_AVAILABLE if nothing to read; 305*479e2648SJackson Cooper-Driver * SFCP_ERROR_BUFFER_TOO_SMALL / *_INVALID_* for validation failures. 306*479e2648SJackson Cooper-Driver * 307*479e2648SJackson Cooper-Driver * \note Decryption/authentication MUST be performed before returning payload to the caller 308*479e2648SJackson Cooper-Driver * when crypto is used. 309*479e2648SJackson Cooper-Driver */ 310*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_receive_msg(uint8_t *buf, size_t buf_size, 311*479e2648SJackson Cooper-Driver bool any_sender, sfcp_node_id_t sender, 312*479e2648SJackson Cooper-Driver uint16_t application_id, uint16_t *client_id, 313*479e2648SJackson Cooper-Driver uint8_t **payload, size_t *payload_len, 314*479e2648SJackson Cooper-Driver struct sfcp_msg_metadata_t *metadata); 315*479e2648SJackson Cooper-Driver 316*479e2648SJackson Cooper-Driver /** 317*479e2648SJackson Cooper-Driver * \brief Receive a reply (polling mode). 318*479e2648SJackson Cooper-Driver * 319*479e2648SJackson Cooper-Driver * \details 320*479e2648SJackson Cooper-Driver * Retrieves the next available reply corresponding to \p metadata (by route), validates it, 321*479e2648SJackson Cooper-Driver * and exposes the plaintext payload pointer and capacity. If nothing is available, returns 322*479e2648SJackson Cooper-Driver * SFCP_ERROR_NO_REPLY_AVAILABLE (non-fatal). 323*479e2648SJackson Cooper-Driver * 324*479e2648SJackson Cooper-Driver * Validation rules enforced include: 325*479e2648SJackson Cooper-Driver * - Packet type MUST be REPLY (normal) or PROTOCOL_ERROR_REPLY (protocol error). 326*479e2648SJackson Cooper-Driver * Error replies are never encrypted. 327*479e2648SJackson Cooper-Driver * - If the message used ID extension, the reply MUST carry the same client_id and application_id. 328*479e2648SJackson Cooper-Driver * - uses_cryptography MUST mirror the original message for normal replies. 329*479e2648SJackson Cooper-Driver * 330*479e2648SJackson Cooper-Driver * \param[in] buf Buffer to receive the packet. 331*479e2648SJackson Cooper-Driver * \param[in] buf_size Size of \p buf. 332*479e2648SJackson Cooper-Driver * \param[in] metadata Reply metadata captured at send time. 333*479e2648SJackson Cooper-Driver * \param[out] payload Pointer within \p buf to the plaintext payload (if any). 334*479e2648SJackson Cooper-Driver * \param[out] payload_len Capacity of \p payload (bytes). 335*479e2648SJackson Cooper-Driver * 336*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 337*479e2648SJackson Cooper-Driver * SFCP_ERROR_NO_REPLY_AVAILABLE if nothing to read; 338*479e2648SJackson Cooper-Driver * SFCP_ERROR_BUFFER_TOO_SMALL / *_INVALID_* for validation failures. 339*479e2648SJackson Cooper-Driver * 340*479e2648SJackson Cooper-Driver * \note Decryption/authentication MUST be performed before returning payload to the caller 341*479e2648SJackson Cooper-Driver * when crypto is used. 342*479e2648SJackson Cooper-Driver */ 343*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_receive_reply(uint8_t *buf, size_t buf_size, 344*479e2648SJackson Cooper-Driver struct sfcp_reply_metadata_t metadata, 345*479e2648SJackson Cooper-Driver uint8_t **payload, size_t *payload_len); 346*479e2648SJackson Cooper-Driver 347*479e2648SJackson Cooper-Driver /** 348*479e2648SJackson Cooper-Driver * \brief Look up the registered message handler for an Application ID. 349*479e2648SJackson Cooper-Driver * 350*479e2648SJackson Cooper-Driver * \param[in] application_id Application ID to route messages to (0 for the 351*479e2648SJackson Cooper-Driver * node-wide/default handler). 352*479e2648SJackson Cooper-Driver * \param[out] handler On success, set to the registered handler. 353*479e2648SJackson Cooper-Driver * 354*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 355*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_APPLICATION_ID if no handler exists; 356*479e2648SJackson Cooper-Driver * other errors as appropriate. 357*479e2648SJackson Cooper-Driver */ 358*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_get_msg_handler(uint16_t application_id, 359*479e2648SJackson Cooper-Driver sfcp_handler_t *handler); 360*479e2648SJackson Cooper-Driver 361*479e2648SJackson Cooper-Driver /** 362*479e2648SJackson Cooper-Driver * \brief Register (or replace) the message handler for an Application ID. 363*479e2648SJackson Cooper-Driver * 364*479e2648SJackson Cooper-Driver * \param[in] application_id Application ID to associate with \p handler 365*479e2648SJackson Cooper-Driver * (0 for the node-wide/default handler). 366*479e2648SJackson Cooper-Driver * \param[in] handler Callback to invoke when a message for this 367*479e2648SJackson Cooper-Driver * Application ID is received. 368*479e2648SJackson Cooper-Driver * 369*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; an error code otherwise. 370*479e2648SJackson Cooper-Driver */ 371*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_register_msg_handler(uint16_t application_id, 372*479e2648SJackson Cooper-Driver sfcp_handler_t handler); 373*479e2648SJackson Cooper-Driver 374*479e2648SJackson Cooper-Driver /** 375*479e2648SJackson Cooper-Driver * \brief Copy a buffered Message out of the internal queue (handler mode). 376*479e2648SJackson Cooper-Driver * 377*479e2648SJackson Cooper-Driver * \details 378*479e2648SJackson Cooper-Driver * On success this function: 379*479e2648SJackson Cooper-Driver * - Performs any required decryption, authentication, and access-control checks 380*479e2648SJackson Cooper-Driver * before exposing data to the caller. 381*479e2648SJackson Cooper-Driver * - Copies the plaintext payload into \p payload (if \p payload_len >= size). 382*479e2648SJackson Cooper-Driver * - Fills \p sender, \p client_id, \p needs_reply, and \p metadata so a reply 383*479e2648SJackson Cooper-Driver * can be constructed later. 384*479e2648SJackson Cooper-Driver * - Removes the Message from the internal buffer. 385*479e2648SJackson Cooper-Driver * 386*479e2648SJackson Cooper-Driver * On failure, the Message MUST NOT be removed from the buffer. 387*479e2648SJackson Cooper-Driver * 388*479e2648SJackson Cooper-Driver * \param[in] buffer_handle Handle previously delivered to a message handler. 389*479e2648SJackson Cooper-Driver * \param[out] sender Set to the Sender node ID. 390*479e2648SJackson Cooper-Driver * \param[out] client_id Set to the Client ID (0 if ID extension not used). 391*479e2648SJackson Cooper-Driver * \param[out] needs_reply Set true if the Message requests a reply. 392*479e2648SJackson Cooper-Driver * \param[out] payload Destination buffer for the plaintext payload 393*479e2648SJackson Cooper-Driver * (may be NULL if \p payload_len is 0). 394*479e2648SJackson Cooper-Driver * \param[in] payload_len Size in bytes of \p payload. 395*479e2648SJackson Cooper-Driver * \param[out] payload_size Set to the number of payload bytes available. 396*479e2648SJackson Cooper-Driver * \param[out] metadata Filled with values needed to initialize a reply. 397*479e2648SJackson Cooper-Driver * 398*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 399*479e2648SJackson Cooper-Driver * SFCP_ERROR_PAYLOAD_TOO_LARGE if \p payload is too small (Message 400*479e2648SJackson Cooper-Driver * is retained internally); 401*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_PACKET / *_INVALID_* on validation failure 402*479e2648SJackson Cooper-Driver * (Message is retained); 403*479e2648SJackson Cooper-Driver * other errors as appropriate. 404*479e2648SJackson Cooper-Driver */ 405*479e2648SJackson Cooper-Driver enum sfcp_error_t 406*479e2648SJackson Cooper-Driver sfcp_pop_msg_from_buffer(sfcp_buffer_handle_t buffer_handle, 407*479e2648SJackson Cooper-Driver sfcp_node_id_t *sender, uint16_t *client_id, 408*479e2648SJackson Cooper-Driver bool *needs_reply, uint8_t *payload, 409*479e2648SJackson Cooper-Driver size_t payload_len, size_t *payload_size, 410*479e2648SJackson Cooper-Driver struct sfcp_msg_metadata_t *metadata); 411*479e2648SJackson Cooper-Driver 412*479e2648SJackson Cooper-Driver /** 413*479e2648SJackson Cooper-Driver * \brief Look up the registered reply handler for a client identifier. 414*479e2648SJackson Cooper-Driver * 415*479e2648SJackson Cooper-Driver * \param[in] client_id Client identifier used to route replies (0 when the 416*479e2648SJackson Cooper-Driver * ID extension is not used). 417*479e2648SJackson Cooper-Driver * \param[out] handler On success, set to the registered handler. 418*479e2648SJackson Cooper-Driver * 419*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 420*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_CLIENT_ID if no handler exists; 421*479e2648SJackson Cooper-Driver * other errors as appropriate. 422*479e2648SJackson Cooper-Driver */ 423*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_get_reply_handler(uint16_t client_id, 424*479e2648SJackson Cooper-Driver sfcp_handler_t *handler); 425*479e2648SJackson Cooper-Driver 426*479e2648SJackson Cooper-Driver /** 427*479e2648SJackson Cooper-Driver * \brief Register (or replace) the reply handler for an identifier. 428*479e2648SJackson Cooper-Driver * 429*479e2648SJackson Cooper-Driver * \details 430*479e2648SJackson Cooper-Driver * The identifier selects which replies are delivered to \p handler. In systems 431*479e2648SJackson Cooper-Driver * using the ID extension this is typically the \b client_id; otherwise it may be 432*479e2648SJackson Cooper-Driver * a single global handler registered with identifier 0. 433*479e2648SJackson Cooper-Driver * 434*479e2648SJackson Cooper-Driver * \param[in] application_id Identifier used by the implementation to select 435*479e2648SJackson Cooper-Driver * the reply handler (commonly the client_id). 436*479e2648SJackson Cooper-Driver * \param[in] handler Callback to invoke when a matching reply arrives. 437*479e2648SJackson Cooper-Driver * 438*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; an error code otherwise. 439*479e2648SJackson Cooper-Driver */ 440*479e2648SJackson Cooper-Driver enum sfcp_error_t sfcp_register_reply_handler(uint16_t application_id, 441*479e2648SJackson Cooper-Driver sfcp_handler_t handler); 442*479e2648SJackson Cooper-Driver 443*479e2648SJackson Cooper-Driver /** 444*479e2648SJackson Cooper-Driver * \brief Copy a buffered Reply out of the internal queue (handler mode). 445*479e2648SJackson Cooper-Driver * 446*479e2648SJackson Cooper-Driver * \details 447*479e2648SJackson Cooper-Driver * On success this function: 448*479e2648SJackson Cooper-Driver * - Performs any required decryption, authentication, and access-control checks 449*479e2648SJackson Cooper-Driver * before exposing data to the caller. 450*479e2648SJackson Cooper-Driver * - Copies the plaintext payload into \p payload (if \p payload_len >= size). 451*479e2648SJackson Cooper-Driver * - Fills \p metadata so the caller can match the Reply to the original Message. 452*479e2648SJackson Cooper-Driver * - Removes the Reply from the internal buffer. 453*479e2648SJackson Cooper-Driver * 454*479e2648SJackson Cooper-Driver * On failure, the Reply MUST NOT be removed from the buffer. 455*479e2648SJackson Cooper-Driver * 456*479e2648SJackson Cooper-Driver * \param[in] buffer_handle Handle previously delivered to a reply handler. 457*479e2648SJackson Cooper-Driver * \param[out] payload Destination buffer for the plaintext payload 458*479e2648SJackson Cooper-Driver * (may be NULL if \p payload_len is 0). 459*479e2648SJackson Cooper-Driver * \param[in] payload_len Size in bytes of \p payload. 460*479e2648SJackson Cooper-Driver * \param[out] payload_size Set to the number of payload bytes available. 461*479e2648SJackson Cooper-Driver * \param[out] metadata Filled with the reply metadata (ids, message_id, flags). 462*479e2648SJackson Cooper-Driver * 463*479e2648SJackson Cooper-Driver * \return SFCP_ERROR_SUCCESS on success; 464*479e2648SJackson Cooper-Driver * SFCP_ERROR_PAYLOAD_TOO_LARGE if \p payload is too small (Reply 465*479e2648SJackson Cooper-Driver * is retained internally); 466*479e2648SJackson Cooper-Driver * SFCP_ERROR_INVALID_PACKET / *_INVALID_* on validation failure 467*479e2648SJackson Cooper-Driver * (Reply is retained); 468*479e2648SJackson Cooper-Driver * other errors as appropriate. 469*479e2648SJackson Cooper-Driver */ 470*479e2648SJackson Cooper-Driver enum sfcp_error_t 471*479e2648SJackson Cooper-Driver sfcp_pop_reply_from_buffer(sfcp_buffer_handle_t buffer_handle, uint8_t *payload, 472*479e2648SJackson Cooper-Driver size_t payload_len, size_t *payload_size, 473*479e2648SJackson Cooper-Driver struct sfcp_reply_metadata_t *metadata); 474*479e2648SJackson Cooper-Driver 475*479e2648SJackson Cooper-Driver #ifdef __cplusplus 476*479e2648SJackson Cooper-Driver } 477*479e2648SJackson Cooper-Driver #endif 478*479e2648SJackson Cooper-Driver 479*479e2648SJackson Cooper-Driver #endif /* __SFCP_H__ */ 480