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