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/compiler.h> 10 #include <libpldm/pldm_types.h> 11 #include <libpldm/utils.h> 12 13 #include <asm/byteorder.h> 14 #include <stdalign.h> 15 #include <stdbool.h> 16 #include <stddef.h> 17 #include <stdint.h> 18 19 typedef uint8_t pldm_tid_t; 20 21 /** @brief PLDM Types 22 */ 23 enum pldm_supported_types { 24 PLDM_BASE = 0x00, 25 PLDM_SMBIOS = 0x01, 26 PLDM_PLATFORM = 0x02, 27 PLDM_BIOS = 0x03, 28 PLDM_FRU = 0x04, 29 PLDM_FWUP = 0x05, 30 PLDM_RDE = 0x06, 31 PLDM_FILE = 0x07, 32 PLDM_OEM = 0x3f, 33 }; 34 35 /** @brief PLDM Commands 36 */ 37 enum pldm_supported_commands { 38 PLDM_SET_TID = 0x1, 39 PLDM_GET_TID = 0x2, 40 PLDM_GET_PLDM_VERSION = 0x3, 41 PLDM_GET_PLDM_TYPES = 0x4, 42 PLDM_GET_PLDM_COMMANDS = 0x5, 43 PLDM_SELECT_PLDM_VERSION = 0x6, 44 PLDM_NEGOTIATE_TRANSFER_PARAMETERS = 0x7, 45 PLDM_MULTIPART_SEND = 0x8, 46 PLDM_MULTIPART_RECEIVE = 0x9, 47 PLDM_GET_MULTIPART_TRANSFER_SUPPORT = 0xa, 48 }; 49 50 /** @brief PLDM base codes 51 */ 52 enum pldm_completion_codes { 53 PLDM_SUCCESS = 0x00, 54 PLDM_ERROR = 0x01, 55 PLDM_ERROR_INVALID_DATA = 0x02, 56 PLDM_ERROR_INVALID_LENGTH = 0x03, 57 PLDM_ERROR_NOT_READY = 0x04, 58 PLDM_ERROR_UNSUPPORTED_PLDM_CMD = 0x05, 59 PLDM_ERROR_INVALID_PLDM_TYPE = 0x20, 60 PLDM_ERROR_INVALID_TRANSFER_CONTEXT = 0x21, 61 PLDM_ERROR_INVALID_DATA_TRANSFER_HANDLE = 0x22, 62 PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION = 0x23, 63 PLDM_ERROR_INVALID_REQUESTED_SECTION_OFFSET = 0x24, 64 65 PLDM_GET_PLDM_VERSION_INVALID_DATA_TRANSFER_HANDLE = 0x80, 66 PLDM_GET_PLDM_VERSION_INVALID_TRANSFER_OPERATION_FLAG = 0x81, 67 PLDM_GET_PLDM_VERSION_INVALID_PLDM_TYPE_IN_REQUEST_DATA = 0x83, 68 69 PLDM_GET_PLDM_COMMANDS_INVALID_PLDM_TYPE_IN_REQUEST_DATA = 0x83, 70 PLDM_GET_PLDM_COMMANDS_INVALID_PLDM_VERSION_IN_REQUEST_DATA = 0x84, 71 72 PLDM_SELECT_PLDM_VERSION_INVALID_PLDM_TYPE_IN_REQUEST_DATA = 0x83, 73 PLDM_SELECT_PLDM_VERSION_INVALID_PLDM_VERSION_IN_REQUEST_DATA = 0x84, 74 75 PLDM_MULTIPART_SEND_NEGOTIATION_INCOMPLETE = 0x83, 76 PLDM_MULTIPART_RECEIVE_NEGOTIATION_INCOMPLETE = 0x83, 77 78 PLDM_GET_MULTIPART_TRANSFER_SUPPORT_INVALID_PLDM_TYPE_IN_REQUEST_DATA = 79 0x83, 80 PLDM_GET_MULTIPART_TRANSFER_SUPPORT_INVALID_PLDM_VERSION_IN_REQUEST_DATA = 81 0x84, 82 }; 83 84 enum transfer_op_flag { 85 PLDM_GET_NEXTPART = 0, 86 PLDM_GET_FIRSTPART = 1, 87 PLDM_ACKNOWLEDGEMENT_ONLY = 2, 88 }; 89 90 enum transfer_multipart_op_flag { 91 PLDM_XFER_FIRST_PART = 0, 92 PLDM_XFER_NEXT_PART = 1, 93 PLDM_XFER_ABORT = 2, 94 PLDM_XFER_COMPLETE = 3, 95 PLDM_XFER_CURRENT_PART = 4, 96 }; 97 98 enum pldm_base_multipart_receive_transfer_flag { 99 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START = 0x01, 100 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_MIDDLE = 0x02, 101 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END = 0x04, 102 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START_AND_END = 0x05, 103 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_ACK_COMPLETION = 0x08, 104 }; 105 106 enum transfer_resp_flag { 107 PLDM_START = 0x01, 108 PLDM_MIDDLE = 0x02, 109 PLDM_END = 0x04, 110 PLDM_START_AND_END = 0x05, 111 PLDM_ACKNOWLEDGE_COMPLETION = 0x08, 112 }; 113 114 /** @brief PLDM transport protocol type 115 */ 116 enum pldm_transport_protocol_type { 117 PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP = 0x00, 118 PLDM_TRANSPORT_PROTOCOL_TYPE_OEM = 0xff, 119 }; 120 121 /** @enum MessageType 122 * 123 * The different message types supported by the PLDM specification. 124 */ 125 typedef enum { 126 PLDM_RESPONSE, //!< PLDM response 127 PLDM_REQUEST, //!< PLDM request 128 PLDM_RESERVED, //!< Reserved 129 PLDM_ASYNC_REQUEST_NOTIFY, //!< Unacknowledged PLDM request messages 130 } MessageType; 131 132 #define PLDM_INSTANCE_MAX 31 133 #define PLDM_MAX_TYPES 64 134 #define PLDM_MAX_CMDS_PER_TYPE 256 135 #define PLDM_MAX_TIDS 256 136 #define PLDM_TID_UNASSIGNED 0x00 137 #define PLDM_TID_RESERVED 0xff 138 139 /* Message payload lengths */ 140 #define PLDM_GET_COMMANDS_REQ_BYTES 5 141 #define PLDM_GET_VERSION_REQ_BYTES 6 142 143 /* Response lengths are inclusive of completion code */ 144 #define PLDM_GET_TYPES_REQ_BYTES 0 145 #define PLDM_GET_TYPES_RESP_BYTES 9 146 #define PLDM_GET_TID_REQ_BYTES 0 147 #define PLDM_GET_TID_RESP_BYTES 2 148 #define PLDM_SET_TID_REQ_BYTES 1 149 #define PLDM_SET_TID_RESP_BYTES 1 150 #define PLDM_GET_COMMANDS_RESP_BYTES 33 151 /* Response data has only one version and does not contain the checksum */ 152 #define PLDM_GET_VERSION_RESP_BYTES 10 153 #define PLDM_MULTIPART_RECEIVE_REQ_BYTES 18 154 #define PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES 10 155 156 #define PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES 10 157 #define PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES 11 158 159 #define PLDM_VERSION_0 0 160 #define PLDM_CURRENT_VERSION PLDM_VERSION_0 161 162 #define PLDM_TIMESTAMP104_SIZE 13 163 164 /** @brief Minimum length of response for a optional PLDM command 165 * 166 * For a optional PLDM command, the command handler might not be 167 * implemented in a device's firmware, a response contains only CC 168 * might come in, such as ERROR_UNSUPPORTED_PLDM_CMD. 169 * 170 * The description can be found in DSP0240: 171 * > For an unsupported PLDM command, the ERROR_UNSUPPORTED_PLDM_CMD 172 * > completion code shall be returned unless the responder is in a 173 * > transient state (not ready), in which it cannot process the PLDM 174 * > command. If the responder is in a transient state, it may return 175 * > the ERROR_NOT_READY completion code. 176 */ 177 #define PLDM_OPTIONAL_COMMAND_RESP_MIN_LEN 1 178 179 /** @struct pldm_msg_hdr 180 * 181 * Structure representing PLDM message header fields 182 */ 183 struct pldm_msg_hdr { 184 #if defined(__LITTLE_ENDIAN_BITFIELD) 185 uint8_t instance_id : 5; //!< Instance ID 186 uint8_t reserved : 1; //!< Reserved 187 uint8_t datagram : 1; //!< Datagram bit 188 uint8_t request : 1; //!< Request bit 189 #elif defined(__BIG_ENDIAN_BITFIELD) 190 uint8_t request : 1; //!< Request bit 191 uint8_t datagram : 1; //!< Datagram bit 192 uint8_t reserved : 1; //!< Reserved 193 uint8_t instance_id : 5; //!< Instance ID 194 #endif 195 196 #if defined(__LITTLE_ENDIAN_BITFIELD) 197 uint8_t type : 6; //!< PLDM type 198 uint8_t header_ver : 2; //!< Header version 199 #elif defined(__BIG_ENDIAN_BITFIELD) 200 uint8_t header_ver : 2; //!< Header version 201 uint8_t type : 6; //!< PLDM type 202 #endif 203 uint8_t command; //!< PLDM command code 204 } __attribute__((packed)); 205 206 // Macros for byte-swapping variables in-place 207 #define HTOLE32(X) ((X) = htole32(X)) 208 #define HTOLE16(X) ((X) = htole16(X)) 209 #define LE32TOH(X) ((X) = le32toh(X)) 210 #define LE16TOH(X) ((X) = le16toh(X)) 211 212 /** @struct pldm_msg 213 * 214 * Structure representing PLDM message 215 */ 216 struct pldm_msg { 217 struct pldm_msg_hdr hdr; //!< PLDM message header 218 uint8_t payload[1]; //!< &payload[0] is the beginning of the payload 219 } __attribute__((packed)); 220 221 /** @brief Determine the underlying object size for a @struct pldm_msg 222 * 223 * @pre @p size must be a constant expression 224 * 225 * @note Providing an expression for @p size that is not an integer constant 226 * expression will force a compilation failure. 227 * 228 * @param size The desired size of the @struct pldm_msg payload 229 */ 230 #define PLDM_MSG_SIZE(size) \ 231 (sizeof(char[(__builtin_constant_p(size)) ? 1 : -1])) * \ 232 (sizeof(struct pldm_msg) - \ 233 sizeof(((struct pldm_msg *)NULL)->payload) + (size)) 234 235 /** @brief Stack-allocate a buffer to hold a @struct pldm_msg 236 * 237 * Allocate an appropriately aligned array named @p name of type unsigned char 238 * with the necessary length to hold a payload of the requested size. 239 * 240 * @param name - The variable name used to define the buffer 241 * @param size - The desired payload length for the intended @struct pldm_msg 242 */ 243 #define PLDM_MSG_BUFFER(name, size) \ 244 alignas(struct pldm_msg) unsigned char(name)[PLDM_MSG_SIZE(size)] 245 246 /** @brief Create a pointer to a stack-allocated @struct pldm_msg 247 * 248 * Define a pointer named @p name of type @struct pldm_msg to an object on the 249 * stack of appropriate alignment and length to hold a @struct pldm_msg with a 250 * payload of @p size. 251 * 252 * @param name - The variable name for pointer 253 * @param size - The desired payload length for the underlying @struct pldm_msg 254 * buffer 255 */ 256 #ifdef __cplusplus 257 #define PLDM_MSG_DEFINE_P(name, size) \ 258 PLDM_MSG_BUFFER(name##_buf, size); \ 259 auto *(name) = new (name##_buf) pldm_msg() 260 #endif 261 262 /** 263 * @brief Compare the headers from two PLDM messages to determine if the latter 264 * is a message representing a response to the former, where the former must be 265 * a request. 266 * 267 * @param[in] req - A pointer to a PLDM header object, which must represent a 268 * request 269 * @param[in] resp - A pointer to a PLDM header object, which may represent a 270 * response to the provided request. 271 * 272 * @return true if the header pointed to by resp represents a message that is a 273 * response to the header pointed to by req, otherwise false. 274 */ 275 bool pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr *req, 276 const struct pldm_msg_hdr *resp); 277 278 /** @brief Convert ver32_t to string 279 * @param[in] version - Pointer to ver32_t 280 * @param[out] buffer - Pointer to the buffer 281 * @param[in] buffer_size - Size of the buffer, up to SSIZE_MAX 282 * @return The number of characters written to the buffer (excluding the null 283 * byte). The converted string may be truncated, and truncation is not 284 * considered an error. The result is negative if invalid arguments are supplied 285 * (NULL values for required pointers or the buffer size is beyond a 286 * representable range). 287 */ 288 ssize_t pldm_base_ver2str(const ver32_t *version, char *buffer, 289 size_t buffer_size); 290 291 /** @struct pldm_header_info 292 * 293 * The information needed to prepare PLDM header and this is passed to the 294 * pack_pldm_header and unpack_pldm_header API. 295 */ 296 struct pldm_header_info { 297 MessageType msg_type; //!< PLDM message type 298 uint8_t instance; //!< PLDM instance id 299 uint8_t pldm_type; //!< PLDM type 300 uint8_t command; //!< PLDM command code 301 uint8_t completion_code; //!< PLDM completion code, applies for response 302 }; 303 304 /** @struct pldm_get_types_resp 305 * 306 * Structure representing PLDM get types response. 307 */ 308 struct pldm_get_types_resp { 309 uint8_t completion_code; //!< completion code 310 bitfield8_t types[8]; //!< each bit represents whether a given PLDM Type 311 //!< is supported 312 } __attribute__((packed)); 313 314 /** @struct pldm_get_commands_req 315 * 316 * Structure representing PLDM get commands request. 317 */ 318 struct pldm_get_commands_req { 319 uint8_t type; //!< PLDM Type for which command support information is 320 //!< being requested 321 ver32_t version; //!< version for the specified PLDM Type 322 } __attribute__((packed)); 323 324 /** @struct pldm_get_commands_resp 325 * 326 * Structure representing PLDM get commands response. 327 */ 328 struct pldm_get_commands_resp { 329 uint8_t completion_code; //!< completion code 330 bitfield8_t commands[32]; //!< each bit represents whether a given PLDM 331 //!< command is supported 332 } __attribute__((packed)); 333 334 /** @struct pldm_get_version_req 335 * 336 * Structure representing PLDM get version request. 337 */ 338 struct pldm_get_version_req { 339 uint32_t transfer_handle; //!< handle to identify PLDM version data transfer 340 uint8_t transfer_opflag; //!< PLDM GetVersion operation flag 341 uint8_t type; //!< PLDM Type for which version information is being requested 342 } __attribute__((packed)); 343 344 /** @struct pldm_get_version_resp 345 * 346 * Structure representing PLDM get version response. 347 */ 348 349 struct pldm_get_version_resp { 350 uint8_t completion_code; //!< completion code 351 uint32_t next_transfer_handle; //!< next portion of PLDM version data 352 //!< transfer 353 uint8_t transfer_flag; //!< PLDM GetVersion transfer flag 354 uint8_t version_data[1]; //!< PLDM GetVersion version field 355 } __attribute__((packed)); 356 357 /** @struct pldm_set_tid_req 358 * 359 * Structure representing PLDM set tid request. 360 */ 361 362 struct pldm_set_tid_req { 363 uint8_t tid; //!< PLDM SetTID TID field 364 } __attribute__((packed)); 365 366 /** @struct pldm_get_tid_resp 367 * 368 * Structure representing PLDM get tid response. 369 */ 370 371 struct pldm_get_tid_resp { 372 uint8_t completion_code; //!< completion code 373 uint8_t tid; //!< PLDM GetTID TID field 374 } __attribute__((packed)); 375 376 /** @struct pldm_base_multipart_receive_req 377 * 378 * Structure representing PLDM multipart receive request. 379 */ 380 struct pldm_base_multipart_receive_req { 381 uint8_t pldm_type; //!< PLDM Type for the MultipartReceive 382 //!< command. 383 uint8_t transfer_opflag; //!< PLDM MultipartReceive operation flag. 384 uint32_t transfer_ctx; //!< Protocol-specifc context for this 385 //!< transfer. 386 uint32_t transfer_handle; //!< handle to identify the part of data to be 387 //!< received. 388 uint32_t section_offset; //!< The start offset for the requested 389 //!< section. 390 uint32_t section_length; //!< The length (in bytes) of the section 391 //!< requested. 392 }; 393 394 /** @struct pldm_base_multipart_receive_resp 395 * 396 * Structure representing PLDM multipart receive request. 397 */ 398 struct pldm_base_multipart_receive_resp { 399 uint8_t completion_code; //!< Completion code of the command. 400 uint8_t transfer_flag; //!< PLDM MultipartReceive transfer flag. 401 uint32_t next_transfer_handle; //!< The handle for the next part of 402 //!< data for this section transfer. 403 struct variable_field data; 404 }; 405 406 /** @struct pldm_base_negotiate_transfer_params_req 407 * 408 * Structure representing PLDM Negotiate Transfer Parameters request 409 */ 410 struct pldm_base_negotiate_transfer_params_req { 411 uint16_t requester_part_size; 412 bitfield8_t requester_protocol_support[8]; 413 }; 414 415 /** @struct pldm_base_negotiate_transfer_params_resp 416 * 417 * Structure representing PLDM Negotiate Transfer Parameters response 418 */ 419 struct pldm_base_negotiate_transfer_params_resp { 420 uint8_t completion_code; 421 uint16_t responder_part_size; 422 bitfield8_t responder_protocol_support[8]; 423 }; 424 425 /** 426 * @brief Populate the PLDM message with the PLDM header.The caller of this API 427 * allocates buffer for the PLDM header when forming the PLDM message. 428 * The buffer is passed to this API to pack the PLDM header. 429 * 430 * @param[in] hdr - Pointer to the PLDM header information 431 * @param[out] msg - Pointer to PLDM message header 432 * 433 * @return 0 on success, otherwise PLDM error codes. 434 * @note Caller is responsible for alloc and dealloc of msg 435 * and hdr params 436 */ 437 uint8_t pack_pldm_header(const struct pldm_header_info *hdr, 438 struct pldm_msg_hdr *msg); 439 440 /** 441 * @brief Unpack the PLDM header from the PLDM message. 442 * 443 * @param[in] msg - Pointer to the PLDM message header 444 * @param[out] hdr - Pointer to the PLDM header information 445 * 446 * @return 0 on success, otherwise PLDM error codes. 447 * @note Caller is responsible for alloc and dealloc of msg 448 * and hdr params 449 */ 450 uint8_t unpack_pldm_header(const struct pldm_msg_hdr *msg, 451 struct pldm_header_info *hdr); 452 453 /* Requester */ 454 455 /* GetPLDMTypes */ 456 457 /** @brief Create a PLDM request message for GetPLDMTypes 458 * 459 * @param[in] instance_id - Message's instance id 460 * @param[in,out] msg - Message will be written to this 461 * @return pldm_completion_codes 462 * @note Caller is responsible for memory alloc and dealloc of param 463 * 'msg.payload' 464 */ 465 int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg); 466 467 /** @brief Decode a GetPLDMTypes response message 468 * 469 * Note: 470 * * If the return value is not PLDM_SUCCESS, it represents a 471 * transport layer error. 472 * * If the completion_code value is not PLDM_SUCCESS, it represents a 473 * protocol layer error and all the out-parameters are invalid. 474 * 475 * @param[in] msg - Response message 476 * @param[in] payload_length - Length of response message payload 477 * @param[out] completion_code - Pointer to response msg's PLDM completion code 478 * @param[out] types - pointer to array bitfield8_t[8] containing supported 479 * types (MAX_TYPES/8) = 8), as per DSP0240 480 * @return pldm_completion_codes 481 */ 482 int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length, 483 uint8_t *completion_code, bitfield8_t *types); 484 485 /* GetPLDMCommands */ 486 487 /** @brief Create a PLDM request message for GetPLDMCommands 488 * 489 * @param[in] instance_id - Message's instance id 490 * @param[in] type - PLDM Type 491 * @param[in] version - Version for PLDM Type 492 * @param[in,out] msg - Message will be written to this 493 * @return pldm_completion_codes 494 * @note Caller is responsible for memory alloc and dealloc of param 495 * 'msg.payload' 496 */ 497 int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version, 498 struct pldm_msg *msg); 499 500 /** @brief Decode a GetPLDMCommands response message 501 * 502 * Note: 503 * * If the return value is not PLDM_SUCCESS, it represents a 504 * transport layer error. 505 * * If the completion_code value is not PLDM_SUCCESS, it represents a 506 * protocol layer error and all the out-parameters are invalid. 507 * 508 * @param[in] msg - Response message 509 * @param[in] payload_length - Length of response message payload 510 * @param[out] completion_code - Pointer to response msg's PLDM completion code 511 * @param[in] commands - pointer to array bitfield8_t[32] containing supported 512 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240 513 * @return pldm_completion_codes 514 */ 515 int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length, 516 uint8_t *completion_code, bitfield8_t *commands); 517 518 /* GetPLDMVersion */ 519 520 /** @brief Create a PLDM request for GetPLDMVersion 521 * 522 * @param[in] instance_id - Message's instance id 523 * @param[in] transfer_handle - Handle to identify PLDM version data transfer. 524 * This handle is ignored by the responder when the 525 * transferop_flag is set to getFirstPart. 526 * @param[in] transfer_opflag - flag to indicate whether it is start of 527 * transfer 528 * @param[in] type - PLDM Type for which version is requested 529 * @param[in,out] msg - Message will be written to this 530 * @return pldm_completion_codes 531 * @note Caller is responsible for memory alloc and dealloc of param 532 * 'msg.payload' 533 */ 534 int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle, 535 uint8_t transfer_opflag, uint8_t type, 536 struct pldm_msg *msg); 537 538 /** @brief Decode a GetPLDMVersion response message 539 * 540 * Note: 541 * * If the return value is not PLDM_SUCCESS, it represents a 542 * transport layer error. 543 * * If the completion_code value is not PLDM_SUCCESS, it represents a 544 * protocol layer error and all the out-parameters are invalid. 545 * 546 * @param[in] msg - Response message 547 * @param[in] payload_length - Length of response message payload 548 * @param[out] completion_code - Pointer to response msg's PLDM completion code 549 * @param[out] next_transfer_handle - the next handle for the next part of data 550 * @param[out] transfer_flag - flag to indicate the part of data 551 * @return pldm_completion_codes 552 */ 553 int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length, 554 uint8_t *completion_code, 555 uint32_t *next_transfer_handle, 556 uint8_t *transfer_flag, ver32_t *version); 557 558 /* GetTID */ 559 560 /** @brief Decode a GetTID response message 561 * 562 * Note: 563 * * If the return value is not PLDM_SUCCESS, it represents a 564 * transport layer error. 565 * * If the completion_code value is not PLDM_SUCCESS, it represents a 566 * protocol layer error and all the out-parameters are invalid. 567 * 568 * @param[in] msg - Response message 569 * @param[in] payload_length - Length of response message payload 570 * @param[out] completion_code - Pointer to response msg's PLDM completion code 571 * @param[out] tid - Pointer to the terminus id 572 * @return pldm_completion_codes 573 */ 574 int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length, 575 uint8_t *completion_code, uint8_t *tid); 576 577 /* Responder */ 578 579 /* GetPLDMTypes */ 580 581 /** @brief Create a PLDM response message for GetPLDMTypes 582 * 583 * @param[in] instance_id - Message's instance id 584 * @param[in] completion_code - PLDM completion code 585 * @param[in] types - pointer to array bitfield8_t[8] containing supported 586 * types (MAX_TYPES/8) = 8), as per DSP0240 587 * @param[in,out] msg - Message will be written to this 588 * @return pldm_completion_codes 589 * @note Caller is responsible for memory alloc and dealloc of param 590 * 'msg.payload' 591 */ 592 int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code, 593 const bitfield8_t *types, struct pldm_msg *msg); 594 595 /* GetPLDMCommands */ 596 597 /** @brief Decode GetPLDMCommands' request data 598 * 599 * @param[in] msg - Request message 600 * @param[in] payload_length - Length of request message payload 601 * @param[out] type - PLDM Type 602 * @param[out] version - Version for PLDM Type 603 * @return pldm_completion_codes 604 */ 605 int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length, 606 uint8_t *type, ver32_t *version); 607 608 /** @brief Create a PLDM response message for GetPLDMCommands 609 * 610 * @param[in] instance_id - Message's instance id 611 * @param[in] completion_code - PLDM completion code 612 * @param[in] commands - pointer to array bitfield8_t[32] containing supported 613 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240 614 * @param[in,out] msg - Message will be written to this 615 * @return pldm_completion_codes 616 * @note Caller is responsible for memory alloc and dealloc of param 617 * 'msg.payload' 618 */ 619 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code, 620 const bitfield8_t *commands, struct pldm_msg *msg); 621 622 /* GetPLDMVersion */ 623 624 /** @brief Create a PLDM response for GetPLDMVersion 625 * 626 * @param[in] instance_id - Message's instance id 627 * @param[in] completion_code - PLDM completion code 628 * @param[in] next_transfer_handle - Handle to identify next portion of 629 * data transfer 630 * @param[in] transfer_flag - Represents the part of transfer 631 * @param[in] version_data - the version data 632 * @param[in] version_size - size of version data 633 * @param[in,out] msg - Message will be written to this 634 * @return pldm_completion_codes 635 * @note Caller is responsible for memory alloc and dealloc of param 636 * 'msg.payload' 637 */ 638 int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code, 639 uint32_t next_transfer_handle, 640 uint8_t transfer_flag, const ver32_t *version_data, 641 size_t version_size, struct pldm_msg *msg); 642 643 /** @brief Decode a GetPLDMVersion request message 644 * 645 * @param[in] msg - Request message 646 * @param[in] payload_length - length of request message payload 647 * @param[out] transfer_handle - the handle of data 648 * @param[out] transfer_opflag - Transfer Flag 649 * @param[out] type - PLDM type for which version is requested 650 * @return pldm_completion_codes 651 */ 652 int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length, 653 uint32_t *transfer_handle, uint8_t *transfer_opflag, 654 uint8_t *type); 655 656 /* Requester */ 657 658 /* GetTID */ 659 660 /** @brief Create a PLDM request message for GetTID 661 * 662 * @param[in] instance_id - Message's instance id 663 * @param[in,out] msg - Message will be written to this 664 * @return pldm_completion_codes 665 * @note Caller is responsible for memory alloc and dealloc of param 666 * 'msg.payload' 667 */ 668 int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg); 669 670 /** @brief Create a PLDM response message for GetTID 671 * 672 * @param[in] instance_id - Message's instance id 673 * @param[in] completion_code - PLDM completion code 674 * @param[in] tid - Terminus ID 675 * @param[in,out] msg - Message will be written to this 676 * @return pldm_completion_codes 677 * @note Caller is responsible for memory alloc and dealloc of param 678 * 'msg.payload' 679 */ 680 int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code, 681 uint8_t tid, struct pldm_msg *msg); 682 683 /** @brief Create a PLDM request message for SetTID 684 * 685 * @param[in] instance_id - Message's instance id 686 * @param[in] tid - Terminus ID 687 * @param[in,out] msg - Message will be written to this 688 * @return pldm_completion_codes 689 * @note Caller is responsible for memory alloc and dealloc of param 690 * 'msg.payload' 691 */ 692 int encode_set_tid_req(uint8_t instance_id, uint8_t tid, struct pldm_msg *msg); 693 694 /** @brief Decode a SetTID request message 695 * 696 * @param[in] msg - Request message 697 * @param[in] payload_length - length of request message payload 698 * @param[out] tid - Terminus ID 699 * @return 0 on success 700 * -EINVAL if the input parameters' memory are not allocated, 701 * or tid is invalid 702 * -EOVERFLOW if the input message length is invalid 703 */ 704 int decode_set_tid_req(const struct pldm_msg *msg, size_t payload_length, 705 uint8_t *tid); 706 707 /* Responder */ 708 709 /* MultipartRecieve */ 710 711 /** @brief Decode a PLDM MultipartReceive request message 712 * 713 * @param[in] msg - Request message 714 * @param[in] payload_length - length of request message payload 715 * @param[out] pldm_type - PLDM type for which version is requested 716 * @param[out] transfer_opflag - Transfer Flag 717 * @param[out] transfer_ctx - The context of the packet 718 * @param[out] transfer_handle - The handle of data 719 * @param[out] section_offset - The start of the requested section 720 * @param[out] section_length - The length of the requested section 721 * @return pldm_completion_codes 722 */ 723 int decode_multipart_receive_req(const struct pldm_msg *msg, 724 size_t payload_length, uint8_t *pldm_type, 725 uint8_t *transfer_opflag, 726 uint32_t *transfer_ctx, 727 uint32_t *transfer_handle, 728 uint32_t *section_offset, 729 uint32_t *section_length); 730 731 /** @brief Encode a PLDM MultipartReceive request message 732 * 733 * @param[in] instance_id - Message's instance id 734 * @param[in] req - The pointer to the request message to be encoded 735 * @param[in,out] msg - Message will be written to this 736 * @param[in, out] payload_length - length of request message payload 737 * @return 0 on success 738 * -EINVAL if the input parameters' memory are not allocated, 739 * or message type or instance in request header is invalid 740 * -ENOMSG if the PLDM type in the request header is invalid 741 * -EOVERFLOW if the input message length is invalid 742 */ 743 int encode_pldm_base_multipart_receive_req( 744 uint8_t instance_id, const struct pldm_base_multipart_receive_req *req, 745 struct pldm_msg *msg, size_t *payload_length); 746 747 /** @brief Decode a PLDM MultipartReceive response message 748 * 749 * @param[in] msg - Response message 750 * @param[in] payload_length - length of request message payload 751 * @param[out] resp - pointer to the decoded response message, 752 * excluding the data integrity checksum 753 * @param[out] data_integrity_checksum - The checksum of data field 754 * of the decoded response message 755 * @return 0 on success 756 * -EINVAL if the input parameters' memory are not allocated 757 * -EOVERFLOW if the input message buffer is too short for the output 758 * response struct 759 * -EBADMSG if the input message buffer is too large for the output 760 * response struct 761 * @note Caller is responsible for memory alloc and dealloc of param 762 * 'msg.payload' 763 */ 764 int decode_pldm_base_multipart_receive_resp( 765 const struct pldm_msg *msg, size_t payload_length, 766 struct pldm_base_multipart_receive_resp *resp, 767 uint32_t *data_integrity_checksum); 768 769 /** @brief Encode a PLDM MultipartReceive response message 770 * 771 * @param[in] instance_id - Message's instance id 772 * @param[in] resp - The pointer to the response message to be encoded 773 * @param[in] checksum - Checksum of the entirely data payload 774 * @param[in,out] msg - Message will be written to this 775 * @param[in,out] payload_length - length of request message payload 776 * @return 0 on success 777 * -EINVAL if argument values are invalid for the invocation 778 * -ENOMSG if the PLDM type in the request header is invalid 779 * -EOVERFLOW if the input message length is invalid 780 * @note Caller is responsible for memory alloc and dealloc of param 781 * 'msg.payload' 782 */ 783 int encode_base_multipart_receive_resp( 784 uint8_t instance_id, 785 const struct pldm_base_multipart_receive_resp *resp, uint32_t checksum, 786 struct pldm_msg *msg, size_t *payload_length); 787 788 /** @brief Create a PLDM response message containing only cc 789 * 790 * @param[in] instance_id - Message's instance id 791 * @param[in] type - PLDM Type 792 * @param[in] command - PLDM Command 793 * @param[in] cc - PLDM Completion Code 794 * @param[out] msg - Message will be written to this 795 * @return pldm_completion_codes 796 */ 797 int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command, 798 uint8_t cc, struct pldm_msg *msg); 799 800 /** @brief Create a PLDM message only with the header 801 * 802 * @param[in] msg_type - PLDM message type 803 * @param[in] instance_id - Message's instance id 804 * @param[in] pldm_type - PLDM Type 805 * @param[in] command - PLDM Command 806 * @param[out] msg - Message will be written to this 807 * 808 * @return pldm_completion_codes 809 */ 810 int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id, 811 uint8_t pldm_type, uint8_t command, 812 struct pldm_msg *msg); 813 814 /** @brief Encode a PLDM Negotiate Transfer Parameters request message 815 * 816 * @param[in] instance_id - Message's instance id 817 * @param[in] req - The pointer to the request message to be encoded 818 * @param[in,out] msg - Message will be written to this 819 * @param[in, out] payload_length - length of request message payload 820 * @return 0 on success 821 * -EINVAL if the input parameters' memory are not allocated, 822 * or message type or instance in request header is invalid 823 * -ENOMSG if the PLDM type in the request header is invalid 824 * -EOVERFLOW if the input message length is invalid 825 */ 826 int encode_pldm_base_negotiate_transfer_params_req( 827 uint8_t instance_id, 828 const struct pldm_base_negotiate_transfer_params_req *req, 829 struct pldm_msg *msg, size_t *payload_length); 830 831 /** @brief Encode a PLDM Negotiate Transfer Parameters response message 832 * 833 * @param[in] instance_id - Message's instance id 834 * @param[in] resp - The pointer to the response message to be encoded 835 * @param[out] msg - Message will be written to this 836 * @param[in,out] payload_length - length of response message payload 837 * @return 0 on success 838 * -EINVAL if the input parameters' memory are not allocated, 839 * or message type or instance in request header is invalid 840 * -ENOMSG if the PLDM type in the request header is invalid 841 * -EOVERFLOW if the input message length is invalid 842 */ 843 int encode_pldm_base_negotiate_transfer_params_resp( 844 uint8_t instance_id, 845 const struct pldm_base_negotiate_transfer_params_resp *resp, 846 struct pldm_msg *msg, size_t *payload_length); 847 848 /** @brief Decode a PLDM Negotiate Transfer Parameters request message 849 * 850 * @param[in] msg - Request message 851 * @param[in] payload_length - length of request message payload 852 * @param[out] req - pointer to the decoded request message 853 * @return 0 on success 854 * -EINVAL if the input parameters' memory are not allocated 855 * -EOVERFLOW if the input message buffer is too short for the output 856 * request struct 857 * -EBADMSG if the input message buffer is too large for the output 858 * request struct 859 * @note Caller is responsible for memory alloc and dealloc of param 860 * 'msg.payload' 861 */ 862 int decode_pldm_base_negotiate_transfer_params_req( 863 const struct pldm_msg *msg, size_t payload_length, 864 struct pldm_base_negotiate_transfer_params_req *req); 865 866 /** @brief Decode a PLDM Negotiate Transfer Parameters response message 867 * 868 * @param[in] msg - Response message 869 * @param[in] payload_length - length of request message payload 870 * @param[out] resp - pointer to the decoded response message, 871 * excluding the data integrity checksum 872 * @return 0 on success 873 * -EINVAL if the input parameters' memory are not allocated 874 * -EOVERFLOW if the input message buffer is too short for the output 875 * response struct 876 * -EBADMSG if the input message buffer is too large for the output 877 * response struct 878 * @note Caller is responsible for memory alloc and dealloc of param 879 * 'msg.payload' 880 */ 881 int decode_pldm_base_negotiate_transfer_params_resp( 882 const struct pldm_msg *msg, size_t payload_length, 883 struct pldm_base_negotiate_transfer_params_resp *resp); 884 885 #ifdef __cplusplus 886 } 887 #endif 888 889 #endif /* BASE_H */ 890