xref: /rk3399_ARM-atf/include/drivers/arm/sfcp.h (revision 2801427972c4b0d4c0165edb509f21186103f21f)
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