xref: /openbmc/libpldm/include/libpldm/base.h (revision 7a3c14ec)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #ifndef BASE_H
3 #define BASE_H
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 #include <libpldm/pldm_types.h>
10 
11 #include <asm/byteorder.h>
12 #include <stdalign.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 typedef uint8_t pldm_tid_t;
18 
19 /** @brief PLDM Types
20  */
21 enum pldm_supported_types {
22 	PLDM_BASE = 0x00,
23 	PLDM_SMBIOS = 0x01,
24 	PLDM_PLATFORM = 0x02,
25 	PLDM_BIOS = 0x03,
26 	PLDM_FRU = 0x04,
27 	PLDM_FWUP = 0x05,
28 	PLDM_RDE = 0x06,
29 	PLDM_OEM = 0x3f,
30 };
31 
32 /** @brief PLDM Commands
33  */
34 enum pldm_supported_commands {
35 	PLDM_SET_TID = 0x1,
36 	PLDM_GET_TID = 0x2,
37 	PLDM_GET_PLDM_VERSION = 0x3,
38 	PLDM_GET_PLDM_TYPES = 0x4,
39 	PLDM_GET_PLDM_COMMANDS = 0x5,
40 	PLDM_MULTIPART_RECEIVE = 0x9,
41 };
42 
43 /** @brief PLDM base codes
44  */
45 enum pldm_completion_codes {
46 	PLDM_SUCCESS = 0x00,
47 	PLDM_ERROR = 0x01,
48 	PLDM_ERROR_INVALID_DATA = 0x02,
49 	PLDM_ERROR_INVALID_LENGTH = 0x03,
50 	PLDM_ERROR_NOT_READY = 0x04,
51 	PLDM_ERROR_UNSUPPORTED_PLDM_CMD = 0x05,
52 	PLDM_ERROR_INVALID_PLDM_TYPE = 0x20,
53 	PLDM_INVALID_TRANSFER_OPERATION_FLAG = 0x21
54 };
55 
56 enum transfer_op_flag {
57 	PLDM_GET_NEXTPART = 0,
58 	PLDM_GET_FIRSTPART = 1,
59 	PLDM_ACKNOWLEDGEMENT_ONLY = 2,
60 };
61 
62 enum transfer_multipart_op_flag {
63 	PLDM_XFER_FIRST_PART = 0,
64 	PLDM_XFER_NEXT_PART = 1,
65 	PLDM_XFER_ABORT = 2,
66 	PLDM_XFER_COMPLETE = 3,
67 	PLDM_XFER_CURRENT_PART = 4,
68 };
69 
70 enum transfer_resp_flag {
71 	PLDM_START = 0x01,
72 	PLDM_MIDDLE = 0x02,
73 	PLDM_END = 0x04,
74 	PLDM_START_AND_END = 0x05,
75 };
76 
77 /** @brief PLDM transport protocol type
78  */
79 enum pldm_transport_protocol_type {
80 	PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP = 0x00,
81 	PLDM_TRANSPORT_PROTOCOL_TYPE_OEM = 0xff,
82 };
83 
84 /** @enum MessageType
85  *
86  *  The different message types supported by the PLDM specification.
87  */
88 typedef enum {
89 	PLDM_RESPONSE,		   //!< PLDM response
90 	PLDM_REQUEST,		   //!< PLDM request
91 	PLDM_RESERVED,		   //!< Reserved
92 	PLDM_ASYNC_REQUEST_NOTIFY, //!< Unacknowledged PLDM request messages
93 } MessageType;
94 
95 #define PLDM_INSTANCE_MAX      31
96 #define PLDM_MAX_TYPES	       64
97 #define PLDM_MAX_CMDS_PER_TYPE 256
98 #define PLDM_MAX_TIDS	       256
99 #define PLDM_TID_UNASSIGNED    0x00
100 #define PLDM_TID_RESERVED      0xff
101 
102 /* Message payload lengths */
103 #define PLDM_GET_COMMANDS_REQ_BYTES 5
104 #define PLDM_GET_VERSION_REQ_BYTES  6
105 
106 /* Response lengths are inclusive of completion code */
107 #define PLDM_GET_TYPES_RESP_BYTES    9
108 #define PLDM_GET_TID_RESP_BYTES	     2
109 #define PLDM_SET_TID_RESP_BYTES	     1
110 #define PLDM_GET_COMMANDS_RESP_BYTES 33
111 /* Response data has only one version and does not contain the checksum */
112 #define PLDM_GET_VERSION_RESP_BYTES	 10
113 #define PLDM_MULTIPART_RECEIVE_REQ_BYTES 18
114 
115 #define PLDM_VERSION_0	     0
116 #define PLDM_CURRENT_VERSION PLDM_VERSION_0
117 
118 #define PLDM_TIMESTAMP104_SIZE 13
119 
120 /** @brief Minimum length of response for a optional PLDM command
121  *
122  *  For a optional PLDM command, the command handler might not be
123  *  implemented in a device's firmware, a response contains only CC
124  *  might come in, such as ERROR_UNSUPPORTED_PLDM_CMD.
125  *
126  *  The description can be found in DSP0240:
127  *  > For an unsupported PLDM command, the ERROR_UNSUPPORTED_PLDM_CMD
128  *  > completion code shall be returned unless the responder is in a
129  *  > transient state (not ready), in which it cannot process the PLDM
130  *  > command. If the responder is in a transient state, it may return
131  *  > the ERROR_NOT_READY completion code.
132  */
133 #define PLDM_OPTIONAL_COMMAND_RESP_MIN_LEN 1
134 
135 /** @struct pldm_msg_hdr
136  *
137  * Structure representing PLDM message header fields
138  */
139 struct pldm_msg_hdr {
140 #if defined(__LITTLE_ENDIAN_BITFIELD)
141 	uint8_t instance_id : 5; //!< Instance ID
142 	uint8_t reserved : 1;	 //!< Reserved
143 	uint8_t datagram : 1;	 //!< Datagram bit
144 	uint8_t request : 1;	 //!< Request bit
145 #elif defined(__BIG_ENDIAN_BITFIELD)
146 	uint8_t request : 1;	 //!< Request bit
147 	uint8_t datagram : 1;	 //!< Datagram bit
148 	uint8_t reserved : 1;	 //!< Reserved
149 	uint8_t instance_id : 5; //!< Instance ID
150 #endif
151 
152 #if defined(__LITTLE_ENDIAN_BITFIELD)
153 	uint8_t type : 6;	//!< PLDM type
154 	uint8_t header_ver : 2; //!< Header version
155 #elif defined(__BIG_ENDIAN_BITFIELD)
156 	uint8_t header_ver : 2; //!< Header version
157 	uint8_t type : 6;	//!< PLDM type
158 #endif
159 	uint8_t command; //!< PLDM command code
160 } __attribute__((packed));
161 
162 // Macros for byte-swapping variables in-place
163 #define HTOLE32(X) ((X) = htole32(X))
164 #define HTOLE16(X) ((X) = htole16(X))
165 #define LE32TOH(X) ((X) = le32toh(X))
166 #define LE16TOH(X) ((X) = le16toh(X))
167 
168 /** @struct pldm_msg
169  *
170  * Structure representing PLDM message
171  */
172 struct pldm_msg {
173 	struct pldm_msg_hdr hdr; //!< PLDM message header
174 	uint8_t payload[1]; //!< &payload[0] is the beginning of the payload
175 } __attribute__((packed));
176 
177 /** @brief Determine the underlying object size for a @struct pldm_msg
178  *
179  * @pre @p size must be a constant expression
180  *
181  * @note Providing an expression for @p size that is not an integer constant
182  *       expression will force a compilation failure.
183  *
184  * @param size The desired size of the @struct pldm_msg payload
185  */
186 #define PLDM_MSG_SIZE(size)                                                    \
187 	(sizeof(char[(__builtin_constant_p(size)) ? 1 : -1])) *                \
188 		(sizeof(struct pldm_msg) -                                     \
189 		 sizeof(((struct pldm_msg *)NULL)->payload) + (size))
190 
191 /** @brief Stack-allocate a buffer to hold a @struct pldm_msg
192  *
193  * Allocate an appropriately aligned array named @p name of type unsigned char
194  * with the necessary length to hold a payload of the requested size.
195  *
196  * @param name - The variable name used to define the buffer
197  * @param size - The desired payload length for the intended @struct pldm_msg
198  */
199 #define PLDM_MSG_BUFFER(name, size)                                            \
200 	alignas(struct pldm_msg) unsigned char(name)[PLDM_MSG_SIZE(size)]
201 
202 /** @brief Create a pointer to a stack-allocated @struct pldm_msg
203  *
204  * Define a pointer named @p name of type @struct pldm_msg to an object on the
205  * stack of appropriate alignment and length to hold a @struct pldm_msg with a
206  * payload of @p size.
207  *
208  * @param name - The variable name for pointer
209  * @param size - The desired payload length for the underlying @struct pldm_msg
210  *        buffer
211  */
212 #ifdef __cplusplus
213 #define PLDM_MSG_DEFINE_P(name, size)                                          \
214 	PLDM_MSG_BUFFER(name##_buf, size);                                     \
215 	auto *(name) = new (name##_buf) pldm_msg
216 #endif
217 
218 /**
219  * @brief Compare the headers from two PLDM messages to determine if the latter
220  * is a message representing a response to the former, where the former must be
221  * a request.
222  *
223  * @param[in] req - A pointer to a PLDM header object, which must represent a
224  *                  request
225  * @param[in] resp - A pointer to a PLDM header object, which may represent a
226  *		     response to the provided request.
227  *
228  * @return true if the header pointed to by resp represents a message that is a
229  *	   response to the header pointed to by req, otherwise false.
230  */
231 bool pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr *req,
232 				     const struct pldm_msg_hdr *resp);
233 
234 /** @struct pldm_header_info
235  *
236  *  The information needed to prepare PLDM header and this is passed to the
237  *  pack_pldm_header and unpack_pldm_header API.
238  */
239 struct pldm_header_info {
240 	MessageType msg_type;	 //!< PLDM message type
241 	uint8_t instance;	 //!< PLDM instance id
242 	uint8_t pldm_type;	 //!< PLDM type
243 	uint8_t command;	 //!< PLDM command code
244 	uint8_t completion_code; //!< PLDM completion code, applies for response
245 };
246 
247 /** @struct pldm_get_types_resp
248  *
249  *  Structure representing PLDM get types response.
250  */
251 struct pldm_get_types_resp {
252 	uint8_t completion_code; //!< completion code
253 	bitfield8_t types[8]; //!< each bit represents whether a given PLDM Type
254 			      //!< is supported
255 } __attribute__((packed));
256 
257 /** @struct pldm_get_commands_req
258  *
259  *  Structure representing PLDM get commands request.
260  */
261 struct pldm_get_commands_req {
262 	uint8_t type;	 //!< PLDM Type for which command support information is
263 			 //!< being requested
264 	ver32_t version; //!< version for the specified PLDM Type
265 } __attribute__((packed));
266 
267 /** @struct pldm_get_commands_resp
268  *
269  *  Structure representing PLDM get commands response.
270  */
271 struct pldm_get_commands_resp {
272 	uint8_t completion_code;  //!< completion code
273 	bitfield8_t commands[32]; //!< each bit represents whether a given PLDM
274 				  //!< command is supported
275 } __attribute__((packed));
276 
277 /** @struct pldm_get_version_req
278  *
279  *  Structure representing PLDM get version request.
280  */
281 struct pldm_get_version_req {
282 	uint32_t transfer_handle; //!< handle to identify PLDM version data transfer
283 	uint8_t transfer_opflag; //!< PLDM GetVersion operation flag
284 	uint8_t type; //!< PLDM Type for which version information is being requested
285 } __attribute__((packed));
286 
287 /** @struct pldm_get_version_resp
288  *
289  *  Structure representing PLDM get version response.
290  */
291 
292 struct pldm_get_version_resp {
293 	uint8_t completion_code;       //!< completion code
294 	uint32_t next_transfer_handle; //!< next portion of PLDM version data
295 				       //!< transfer
296 	uint8_t transfer_flag;	       //!< PLDM GetVersion transfer flag
297 	uint8_t version_data[1];       //!< PLDM GetVersion version field
298 } __attribute__((packed));
299 
300 /** @struct pldm_set_tid_req
301  *
302  *  Structure representing PLDM set tid request.
303  */
304 
305 struct pldm_set_tid_req {
306 	uint8_t tid; //!< PLDM SetTID TID field
307 } __attribute__((packed));
308 
309 /** @struct pldm_get_tid_resp
310  *
311  *  Structure representing PLDM get tid response.
312  */
313 
314 struct pldm_get_tid_resp {
315 	uint8_t completion_code; //!< completion code
316 	uint8_t tid;		 //!< PLDM GetTID TID field
317 } __attribute__((packed));
318 
319 /** @struct pldm_multipart_receive_req
320  *
321  * Structure representing PLDM multipart receive request.
322  */
323 struct pldm_multipart_receive_req {
324 	uint8_t pldm_type;	  //!< PLDM Type for the MultipartReceive
325 				  //!< command.
326 	uint8_t transfer_opflag;  //!< PLDM MultipartReceive operation flag.
327 	uint32_t transfer_ctx;	  //!< Protocol-specifc context for this
328 				  //!< transfer.
329 	uint32_t transfer_handle; //!< handle to identify the part of data to be
330 				  //!< received.
331 	uint32_t section_offset;  //!< The start offset for the requested
332 				  //!< section.
333 	uint32_t section_length;  //!< The length (in bytes) of the section
334 				  //!< requested.
335 } __attribute__((packed));
336 /**
337  * @brief Populate the PLDM message with the PLDM header.The caller of this API
338  *        allocates buffer for the PLDM header when forming the PLDM message.
339  *        The buffer is passed to this API to pack the PLDM header.
340  *
341  * @param[in] hdr - Pointer to the PLDM header information
342  * @param[out] msg - Pointer to PLDM message header
343  *
344  * @return 0 on success, otherwise PLDM error codes.
345  * @note   Caller is responsible for alloc and dealloc of msg
346  *         and hdr params
347  */
348 uint8_t pack_pldm_header(const struct pldm_header_info *hdr,
349 			 struct pldm_msg_hdr *msg);
350 
351 /**
352  * @brief Unpack the PLDM header from the PLDM message.
353  *
354  * @param[in] msg - Pointer to the PLDM message header
355  * @param[out] hdr - Pointer to the PLDM header information
356  *
357  * @return 0 on success, otherwise PLDM error codes.
358  * @note   Caller is responsible for alloc and dealloc of msg
359  *         and hdr params
360  */
361 uint8_t unpack_pldm_header(const struct pldm_msg_hdr *msg,
362 			   struct pldm_header_info *hdr);
363 
364 /* Requester */
365 
366 /* GetPLDMTypes */
367 
368 /** @brief Create a PLDM request message for GetPLDMTypes
369  *
370  *  @param[in] instance_id - Message's instance id
371  *  @param[in,out] msg - Message will be written to this
372  *  @return pldm_completion_codes
373  *  @note  Caller is responsible for memory alloc and dealloc of param
374  *         'msg.payload'
375  */
376 int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg);
377 
378 /** @brief Decode a GetPLDMTypes response message
379  *
380  *  Note:
381  *  * If the return value is not PLDM_SUCCESS, it represents a
382  * transport layer error.
383  *  * If the completion_code value is not PLDM_SUCCESS, it represents a
384  * protocol layer error and all the out-parameters are invalid.
385  *
386  *  @param[in] msg - Response message
387  *  @param[in] payload_length - Length of response message payload
388  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
389  *  @param[out] types - pointer to array bitfield8_t[8] containing supported
390  *              types (MAX_TYPES/8) = 8), as per DSP0240
391  *  @return pldm_completion_codes
392  */
393 int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length,
394 			  uint8_t *completion_code, bitfield8_t *types);
395 
396 /* GetPLDMCommands */
397 
398 /** @brief Create a PLDM request message for GetPLDMCommands
399  *
400  *  @param[in] instance_id - Message's instance id
401  *  @param[in] type - PLDM Type
402  *  @param[in] version - Version for PLDM Type
403  *  @param[in,out] msg - Message will be written to this
404  *  @return pldm_completion_codes
405  *  @note  Caller is responsible for memory alloc and dealloc of param
406  *         'msg.payload'
407  */
408 int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
409 			    struct pldm_msg *msg);
410 
411 /** @brief Decode a GetPLDMCommands response message
412  *
413  *  Note:
414  *  * If the return value is not PLDM_SUCCESS, it represents a
415  * transport layer error.
416  *  * If the completion_code value is not PLDM_SUCCESS, it represents a
417  * protocol layer error and all the out-parameters are invalid.
418  *
419  *  @param[in] msg - Response message
420  *  @param[in] payload_length - Length of response message payload
421  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
422  *  @param[in] commands - pointer to array bitfield8_t[32] containing supported
423  *             commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
424  *  @return pldm_completion_codes
425  */
426 int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length,
427 			     uint8_t *completion_code, bitfield8_t *commands);
428 
429 /* GetPLDMVersion */
430 
431 /** @brief Create a PLDM request for GetPLDMVersion
432  *
433  *  @param[in] instance_id - Message's instance id
434  *  @param[in] transfer_handle - Handle to identify PLDM version data transfer.
435  *         This handle is ignored by the responder when the
436  *         transferop_flag is set to getFirstPart.
437  *  @param[in] transfer_opflag - flag to indicate whether it is start of
438  *         transfer
439  *  @param[in] type -  PLDM Type for which version is requested
440  *  @param[in,out] msg - Message will be written to this
441  *  @return pldm_completion_codes
442  *  @note  Caller is responsible for memory alloc and dealloc of param
443  *         'msg.payload'
444  */
445 int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
446 			   uint8_t transfer_opflag, uint8_t type,
447 			   struct pldm_msg *msg);
448 
449 /** @brief Decode a GetPLDMVersion response message
450  *
451  *  Note:
452  *  * If the return value is not PLDM_SUCCESS, it represents a
453  * transport layer error.
454  *  * If the completion_code value is not PLDM_SUCCESS, it represents a
455  * protocol layer error and all the out-parameters are invalid.
456  *
457  *  @param[in] msg - Response message
458  *  @param[in] payload_length - Length of response message payload
459  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
460  *  @param[out] next_transfer_handle - the next handle for the next part of data
461  *  @param[out] transfer_flag - flag to indicate the part of data
462  *  @return pldm_completion_codes
463  */
464 int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length,
465 			    uint8_t *completion_code,
466 			    uint32_t *next_transfer_handle,
467 			    uint8_t *transfer_flag, ver32_t *version);
468 
469 /* GetTID */
470 
471 /** @brief Decode a GetTID response message
472  *
473  *  Note:
474  *  * If the return value is not PLDM_SUCCESS, it represents a
475  * transport layer error.
476  *  * If the completion_code value is not PLDM_SUCCESS, it represents a
477  * protocol layer error and all the out-parameters are invalid.
478  *
479  *  @param[in] msg - Response message
480  *  @param[in] payload_length - Length of response message payload
481  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
482  *  @param[out] tid - Pointer to the terminus id
483  *  @return pldm_completion_codes
484  */
485 int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length,
486 			uint8_t *completion_code, uint8_t *tid);
487 
488 /* Responder */
489 
490 /* GetPLDMTypes */
491 
492 /** @brief Create a PLDM response message for GetPLDMTypes
493  *
494  *  @param[in] instance_id - Message's instance id
495  *  @param[in] completion_code - PLDM completion code
496  *  @param[in] types - pointer to array bitfield8_t[8] containing supported
497  *             types (MAX_TYPES/8) = 8), as per DSP0240
498  *  @param[in,out] msg - Message will be written to this
499  *  @return pldm_completion_codes
500  *  @note  Caller is responsible for memory alloc and dealloc of param
501  *         'msg.payload'
502  */
503 int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
504 			  const bitfield8_t *types, struct pldm_msg *msg);
505 
506 /* GetPLDMCommands */
507 
508 /** @brief Decode GetPLDMCommands' request data
509  *
510  *  @param[in] msg - Request message
511  *  @param[in] payload_length - Length of request message payload
512  *  @param[out] type - PLDM Type
513  *  @param[out] version - Version for PLDM Type
514  *  @return pldm_completion_codes
515  */
516 int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length,
517 			    uint8_t *type, ver32_t *version);
518 
519 /** @brief Create a PLDM response message for GetPLDMCommands
520  *
521  *  @param[in] instance_id - Message's instance id
522  *  @param[in] completion_code - PLDM completion code
523  *  @param[in] commands - pointer to array bitfield8_t[32] containing supported
524  *             commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
525  *  @param[in,out] msg - Message will be written to this
526  *  @return pldm_completion_codes
527  *  @note  Caller is responsible for memory alloc and dealloc of param
528  *         'msg.payload'
529  */
530 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
531 			     const bitfield8_t *commands, struct pldm_msg *msg);
532 
533 /* GetPLDMVersion */
534 
535 /** @brief Create a PLDM response for GetPLDMVersion
536  *
537  *  @param[in] instance_id - Message's instance id
538  *  @param[in] completion_code - PLDM completion code
539  *  @param[in] next_transfer_handle - Handle to identify next portion of
540  *              data transfer
541  *  @param[in] transfer_flag - Represents the part of transfer
542  *  @param[in] version_data - the version data
543  *  @param[in] version_size - size of version data
544  *  @param[in,out] msg - Message will be written to this
545  *  @return pldm_completion_codes
546  *  @note  Caller is responsible for memory alloc and dealloc of param
547  *         'msg.payload'
548  */
549 int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
550 			    uint32_t next_transfer_handle,
551 			    uint8_t transfer_flag, const ver32_t *version_data,
552 			    size_t version_size, struct pldm_msg *msg);
553 
554 /** @brief Decode a GetPLDMVersion request message
555  *
556  *  @param[in] msg - Request message
557  *  @param[in] payload_length - length of request message payload
558  *  @param[out] transfer_handle - the handle of data
559  *  @param[out] transfer_opflag - Transfer Flag
560  *  @param[out] type - PLDM type for which version is requested
561  *  @return pldm_completion_codes
562  */
563 int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length,
564 			   uint32_t *transfer_handle, uint8_t *transfer_opflag,
565 			   uint8_t *type);
566 
567 /* Requester */
568 
569 /* GetTID */
570 
571 /** @brief Create a PLDM request message for GetTID
572  *
573  *  @param[in] instance_id - Message's instance id
574  *  @param[in,out] msg - Message will be written to this
575  *  @return pldm_completion_codes
576  *  @note  Caller is responsible for memory alloc and dealloc of param
577  *         'msg.payload'
578  */
579 int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg);
580 
581 /** @brief Create a PLDM response message for GetTID
582  *
583  *  @param[in] instance_id - Message's instance id
584  *  @param[in] completion_code - PLDM completion code
585  *  @param[in] tid - Terminus ID
586  *  @param[in,out] msg - Message will be written to this
587  *  @return pldm_completion_codes
588  *  @note  Caller is responsible for memory alloc and dealloc of param
589  *         'msg.payload'
590  */
591 int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code,
592 			uint8_t tid, struct pldm_msg *msg);
593 
594 /** @brief Create a PLDM request message for SetTID
595  *
596  *  @param[in] instance_id - Message's instance id
597  *  @param[in] tid - Terminus ID
598  *  @param[in,out] msg - Message will be written to this
599  *  @return pldm_completion_codes
600  *  @note  Caller is responsible for memory alloc and dealloc of param
601  *         'msg.payload'
602  */
603 int encode_set_tid_req(uint8_t instance_id, uint8_t tid, struct pldm_msg *msg);
604 
605 /* Responder */
606 
607 /* MultipartRecieve */
608 
609 /** @brief Decode a PLDM MultipartReceive request message
610  *
611  *  @param[in] msg - Request message
612  *  @param[in] payload_length - length of request message payload
613  *  @param[out] pldm_type - PLDM type for which version is requested
614  *  @param[out] transfer_opflag - Transfer Flag
615  *  @param[out] transfer_ctx - The context of the packet
616  *  @param[out] transfer_handle - The handle of data
617  *  @param[out] section_offset - The start of the requested section
618  *  @param[out] section_length - The length of the requested section
619  *  @return pldm_completion_codes
620  */
621 int decode_multipart_receive_req(const struct pldm_msg *msg,
622 				 size_t payload_length, uint8_t *pldm_type,
623 				 uint8_t *transfer_opflag,
624 				 uint32_t *transfer_ctx,
625 				 uint32_t *transfer_handle,
626 				 uint32_t *section_offset,
627 				 uint32_t *section_length);
628 
629 /** @brief Create a PLDM response message containing only cc
630  *
631  *  @param[in] instance_id - Message's instance id
632  *  @param[in] type - PLDM Type
633  *  @param[in] command - PLDM Command
634  *  @param[in] cc - PLDM Completion Code
635  *  @param[out] msg - Message will be written to this
636  *  @return pldm_completion_codes
637  */
638 int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command,
639 			uint8_t cc, struct pldm_msg *msg);
640 
641 /** @brief Create a PLDM message only with the header
642  *
643  *	@param[in] msg_type - PLDM message type
644  *	@param[in] instance_id - Message's instance id
645  *	@param[in] pldm_type - PLDM Type
646  *	@param[in] command - PLDM Command
647  *	@param[out] msg - Message will be written to this
648  *
649  *	@return pldm_completion_codes
650  */
651 int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id,
652 			    uint8_t pldm_type, uint8_t command,
653 			    struct pldm_msg *msg);
654 
655 #ifdef __cplusplus
656 }
657 #endif
658 
659 #endif /* BASE_H */
660