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