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 /** @struct pldm_header_info 279 * 280 * The information needed to prepare PLDM header and this is passed to the 281 * pack_pldm_header and unpack_pldm_header API. 282 */ 283 struct pldm_header_info { 284 MessageType msg_type; //!< PLDM message type 285 uint8_t instance; //!< PLDM instance id 286 uint8_t pldm_type; //!< PLDM type 287 uint8_t command; //!< PLDM command code 288 uint8_t completion_code; //!< PLDM completion code, applies for response 289 }; 290 291 /** @struct pldm_get_types_resp 292 * 293 * Structure representing PLDM get types response. 294 */ 295 struct pldm_get_types_resp { 296 uint8_t completion_code; //!< completion code 297 bitfield8_t types[8]; //!< each bit represents whether a given PLDM Type 298 //!< is supported 299 } __attribute__((packed)); 300 301 /** @struct pldm_get_commands_req 302 * 303 * Structure representing PLDM get commands request. 304 */ 305 struct pldm_get_commands_req { 306 uint8_t type; //!< PLDM Type for which command support information is 307 //!< being requested 308 ver32_t version; //!< version for the specified PLDM Type 309 } __attribute__((packed)); 310 311 /** @struct pldm_get_commands_resp 312 * 313 * Structure representing PLDM get commands response. 314 */ 315 struct pldm_get_commands_resp { 316 uint8_t completion_code; //!< completion code 317 bitfield8_t commands[32]; //!< each bit represents whether a given PLDM 318 //!< command is supported 319 } __attribute__((packed)); 320 321 /** @struct pldm_get_version_req 322 * 323 * Structure representing PLDM get version request. 324 */ 325 struct pldm_get_version_req { 326 uint32_t transfer_handle; //!< handle to identify PLDM version data transfer 327 uint8_t transfer_opflag; //!< PLDM GetVersion operation flag 328 uint8_t type; //!< PLDM Type for which version information is being requested 329 } __attribute__((packed)); 330 331 /** @struct pldm_get_version_resp 332 * 333 * Structure representing PLDM get version response. 334 */ 335 336 struct pldm_get_version_resp { 337 uint8_t completion_code; //!< completion code 338 uint32_t next_transfer_handle; //!< next portion of PLDM version data 339 //!< transfer 340 uint8_t transfer_flag; //!< PLDM GetVersion transfer flag 341 uint8_t version_data[1]; //!< PLDM GetVersion version field 342 } __attribute__((packed)); 343 344 /** @struct pldm_set_tid_req 345 * 346 * Structure representing PLDM set tid request. 347 */ 348 349 struct pldm_set_tid_req { 350 uint8_t tid; //!< PLDM SetTID TID field 351 } __attribute__((packed)); 352 353 /** @struct pldm_get_tid_resp 354 * 355 * Structure representing PLDM get tid response. 356 */ 357 358 struct pldm_get_tid_resp { 359 uint8_t completion_code; //!< completion code 360 uint8_t tid; //!< PLDM GetTID TID field 361 } __attribute__((packed)); 362 363 /** @struct pldm_base_multipart_receive_req 364 * 365 * Structure representing PLDM multipart receive request. 366 */ 367 struct pldm_base_multipart_receive_req { 368 uint8_t pldm_type; //!< PLDM Type for the MultipartReceive 369 //!< command. 370 uint8_t transfer_opflag; //!< PLDM MultipartReceive operation flag. 371 uint32_t transfer_ctx; //!< Protocol-specifc context for this 372 //!< transfer. 373 uint32_t transfer_handle; //!< handle to identify the part of data to be 374 //!< received. 375 uint32_t section_offset; //!< The start offset for the requested 376 //!< section. 377 uint32_t section_length; //!< The length (in bytes) of the section 378 //!< requested. 379 }; 380 381 /** @struct pldm_base_multipart_receive_resp 382 * 383 * Structure representing PLDM multipart receive request. 384 */ 385 struct pldm_base_multipart_receive_resp { 386 uint8_t completion_code; //!< Completion code of the command. 387 uint8_t transfer_flag; //!< PLDM MultipartReceive transfer flag. 388 uint32_t next_transfer_handle; //!< The handle for the next part of 389 //!< data for this section transfer. 390 struct variable_field data; 391 }; 392 393 /** @struct pldm_base_negotiate_transfer_params_req 394 * 395 * Structure representing PLDM Negotiate Transfer Parameters request 396 */ 397 struct pldm_base_negotiate_transfer_params_req { 398 uint16_t requester_part_size; 399 bitfield8_t requester_protocol_support[8]; 400 }; 401 402 /** @struct pldm_base_negotiate_transfer_params_resp 403 * 404 * Structure representing PLDM Negotiate Transfer Parameters response 405 */ 406 struct pldm_base_negotiate_transfer_params_resp { 407 uint8_t completion_code; 408 uint16_t responder_part_size; 409 bitfield8_t responder_protocol_support[8]; 410 }; 411 412 /** 413 * @brief Populate the PLDM message with the PLDM header.The caller of this API 414 * allocates buffer for the PLDM header when forming the PLDM message. 415 * The buffer is passed to this API to pack the PLDM header. 416 * 417 * @param[in] hdr - Pointer to the PLDM header information 418 * @param[out] msg - Pointer to PLDM message header 419 * 420 * @return 0 on success, otherwise PLDM error codes. 421 * @note Caller is responsible for alloc and dealloc of msg 422 * and hdr params 423 */ 424 uint8_t pack_pldm_header(const struct pldm_header_info *hdr, 425 struct pldm_msg_hdr *msg); 426 427 /** 428 * @brief Unpack the PLDM header from the PLDM message. 429 * 430 * @param[in] msg - Pointer to the PLDM message header 431 * @param[out] hdr - Pointer to the PLDM header information 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 unpack_pldm_header(const struct pldm_msg_hdr *msg, 438 struct pldm_header_info *hdr); 439 440 /* Requester */ 441 442 /* GetPLDMTypes */ 443 444 /** @brief Create a PLDM request message for GetPLDMTypes 445 * 446 * @param[in] instance_id - Message's instance id 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_types_req(uint8_t instance_id, struct pldm_msg *msg); 453 454 /** @brief Decode a GetPLDMTypes response message 455 * 456 * Note: 457 * * If the return value is not PLDM_SUCCESS, it represents a 458 * transport layer error. 459 * * If the completion_code value is not PLDM_SUCCESS, it represents a 460 * protocol layer error and all the out-parameters are invalid. 461 * 462 * @param[in] msg - Response message 463 * @param[in] payload_length - Length of response message payload 464 * @param[out] completion_code - Pointer to response msg's PLDM completion code 465 * @param[out] types - pointer to array bitfield8_t[8] containing supported 466 * types (MAX_TYPES/8) = 8), as per DSP0240 467 * @return pldm_completion_codes 468 */ 469 int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length, 470 uint8_t *completion_code, bitfield8_t *types); 471 472 /* GetPLDMCommands */ 473 474 /** @brief Create a PLDM request message for GetPLDMCommands 475 * 476 * @param[in] instance_id - Message's instance id 477 * @param[in] type - PLDM Type 478 * @param[in] version - Version for PLDM Type 479 * @param[in,out] msg - Message will be written to this 480 * @return pldm_completion_codes 481 * @note Caller is responsible for memory alloc and dealloc of param 482 * 'msg.payload' 483 */ 484 int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version, 485 struct pldm_msg *msg); 486 487 /** @brief Decode a GetPLDMCommands response message 488 * 489 * Note: 490 * * If the return value is not PLDM_SUCCESS, it represents a 491 * transport layer error. 492 * * If the completion_code value is not PLDM_SUCCESS, it represents a 493 * protocol layer error and all the out-parameters are invalid. 494 * 495 * @param[in] msg - Response message 496 * @param[in] payload_length - Length of response message payload 497 * @param[out] completion_code - Pointer to response msg's PLDM completion code 498 * @param[in] commands - pointer to array bitfield8_t[32] containing supported 499 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240 500 * @return pldm_completion_codes 501 */ 502 int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length, 503 uint8_t *completion_code, bitfield8_t *commands); 504 505 /* GetPLDMVersion */ 506 507 /** @brief Create a PLDM request for GetPLDMVersion 508 * 509 * @param[in] instance_id - Message's instance id 510 * @param[in] transfer_handle - Handle to identify PLDM version data transfer. 511 * This handle is ignored by the responder when the 512 * transferop_flag is set to getFirstPart. 513 * @param[in] transfer_opflag - flag to indicate whether it is start of 514 * transfer 515 * @param[in] type - PLDM Type for which version is requested 516 * @param[in,out] msg - Message will be written to this 517 * @return pldm_completion_codes 518 * @note Caller is responsible for memory alloc and dealloc of param 519 * 'msg.payload' 520 */ 521 int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle, 522 uint8_t transfer_opflag, uint8_t type, 523 struct pldm_msg *msg); 524 525 /** @brief Decode a GetPLDMVersion response message 526 * 527 * Note: 528 * * If the return value is not PLDM_SUCCESS, it represents a 529 * transport layer error. 530 * * If the completion_code value is not PLDM_SUCCESS, it represents a 531 * protocol layer error and all the out-parameters are invalid. 532 * 533 * @param[in] msg - Response message 534 * @param[in] payload_length - Length of response message payload 535 * @param[out] completion_code - Pointer to response msg's PLDM completion code 536 * @param[out] next_transfer_handle - the next handle for the next part of data 537 * @param[out] transfer_flag - flag to indicate the part of data 538 * @return pldm_completion_codes 539 */ 540 int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length, 541 uint8_t *completion_code, 542 uint32_t *next_transfer_handle, 543 uint8_t *transfer_flag, ver32_t *version); 544 545 /* GetTID */ 546 547 /** @brief Decode a GetTID response message 548 * 549 * Note: 550 * * If the return value is not PLDM_SUCCESS, it represents a 551 * transport layer error. 552 * * If the completion_code value is not PLDM_SUCCESS, it represents a 553 * protocol layer error and all the out-parameters are invalid. 554 * 555 * @param[in] msg - Response message 556 * @param[in] payload_length - Length of response message payload 557 * @param[out] completion_code - Pointer to response msg's PLDM completion code 558 * @param[out] tid - Pointer to the terminus id 559 * @return pldm_completion_codes 560 */ 561 int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length, 562 uint8_t *completion_code, uint8_t *tid); 563 564 /* Responder */ 565 566 /* GetPLDMTypes */ 567 568 /** @brief Create a PLDM response message for GetPLDMTypes 569 * 570 * @param[in] instance_id - Message's instance id 571 * @param[in] completion_code - PLDM completion code 572 * @param[in] types - pointer to array bitfield8_t[8] containing supported 573 * types (MAX_TYPES/8) = 8), as per DSP0240 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_types_resp(uint8_t instance_id, uint8_t completion_code, 580 const bitfield8_t *types, struct pldm_msg *msg); 581 582 /* GetPLDMCommands */ 583 584 /** @brief Decode GetPLDMCommands' request data 585 * 586 * @param[in] msg - Request message 587 * @param[in] payload_length - Length of request message payload 588 * @param[out] type - PLDM Type 589 * @param[out] version - Version for PLDM Type 590 * @return pldm_completion_codes 591 */ 592 int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length, 593 uint8_t *type, ver32_t *version); 594 595 /** @brief Create a PLDM response message for GetPLDMCommands 596 * 597 * @param[in] instance_id - Message's instance id 598 * @param[in] completion_code - PLDM completion code 599 * @param[in] commands - pointer to array bitfield8_t[32] containing supported 600 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240 601 * @param[in,out] msg - Message will be written to this 602 * @return pldm_completion_codes 603 * @note Caller is responsible for memory alloc and dealloc of param 604 * 'msg.payload' 605 */ 606 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code, 607 const bitfield8_t *commands, struct pldm_msg *msg); 608 609 /* GetPLDMVersion */ 610 611 /** @brief Create a PLDM response for GetPLDMVersion 612 * 613 * @param[in] instance_id - Message's instance id 614 * @param[in] completion_code - PLDM completion code 615 * @param[in] next_transfer_handle - Handle to identify next portion of 616 * data transfer 617 * @param[in] transfer_flag - Represents the part of transfer 618 * @param[in] version_data - the version data 619 * @param[in] version_size - size of version data 620 * @param[in,out] msg - Message will be written to this 621 * @return pldm_completion_codes 622 * @note Caller is responsible for memory alloc and dealloc of param 623 * 'msg.payload' 624 */ 625 int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code, 626 uint32_t next_transfer_handle, 627 uint8_t transfer_flag, const ver32_t *version_data, 628 size_t version_size, struct pldm_msg *msg); 629 630 /** @brief Decode a GetPLDMVersion request message 631 * 632 * @param[in] msg - Request message 633 * @param[in] payload_length - length of request message payload 634 * @param[out] transfer_handle - the handle of data 635 * @param[out] transfer_opflag - Transfer Flag 636 * @param[out] type - PLDM type for which version is requested 637 * @return pldm_completion_codes 638 */ 639 int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length, 640 uint32_t *transfer_handle, uint8_t *transfer_opflag, 641 uint8_t *type); 642 643 /* Requester */ 644 645 /* GetTID */ 646 647 /** @brief Create a PLDM request message for GetTID 648 * 649 * @param[in] instance_id - Message's instance id 650 * @param[in,out] msg - Message will be written to this 651 * @return pldm_completion_codes 652 * @note Caller is responsible for memory alloc and dealloc of param 653 * 'msg.payload' 654 */ 655 int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg); 656 657 /** @brief Create a PLDM response message for GetTID 658 * 659 * @param[in] instance_id - Message's instance id 660 * @param[in] completion_code - PLDM completion code 661 * @param[in] tid - Terminus ID 662 * @param[in,out] msg - Message will be written to this 663 * @return pldm_completion_codes 664 * @note Caller is responsible for memory alloc and dealloc of param 665 * 'msg.payload' 666 */ 667 int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code, 668 uint8_t tid, struct pldm_msg *msg); 669 670 /** @brief Create a PLDM request message for SetTID 671 * 672 * @param[in] instance_id - Message's instance id 673 * @param[in] tid - Terminus ID 674 * @param[in,out] msg - Message will be written to this 675 * @return pldm_completion_codes 676 * @note Caller is responsible for memory alloc and dealloc of param 677 * 'msg.payload' 678 */ 679 int encode_set_tid_req(uint8_t instance_id, uint8_t tid, struct pldm_msg *msg); 680 681 /** @brief Decode a SetTID request message 682 * 683 * @param[in] msg - Request message 684 * @param[in] payload_length - length of request message payload 685 * @param[out] tid - Terminus ID 686 * @return 0 on success 687 * -EINVAL if the input parameters' memory are not allocated, 688 * or tid is invalid 689 * -EOVERFLOW if the input message length is invalid 690 */ 691 int decode_set_tid_req(const struct pldm_msg *msg, size_t payload_length, 692 uint8_t *tid); 693 694 /* Responder */ 695 696 /* MultipartRecieve */ 697 698 /** @brief Decode a PLDM MultipartReceive request message 699 * 700 * @param[in] msg - Request message 701 * @param[in] payload_length - length of request message payload 702 * @param[out] pldm_type - PLDM type for which version is requested 703 * @param[out] transfer_opflag - Transfer Flag 704 * @param[out] transfer_ctx - The context of the packet 705 * @param[out] transfer_handle - The handle of data 706 * @param[out] section_offset - The start of the requested section 707 * @param[out] section_length - The length of the requested section 708 * @return pldm_completion_codes 709 */ 710 int decode_multipart_receive_req(const struct pldm_msg *msg, 711 size_t payload_length, uint8_t *pldm_type, 712 uint8_t *transfer_opflag, 713 uint32_t *transfer_ctx, 714 uint32_t *transfer_handle, 715 uint32_t *section_offset, 716 uint32_t *section_length); 717 718 /** @brief Encode a PLDM MultipartReceive request message 719 * 720 * @param[in] instance_id - Message's instance id 721 * @param[in] req - The pointer to the request message to be encoded 722 * @param[in,out] msg - Message will be written to this 723 * @param[in, out] payload_length - length of request message payload 724 * @return 0 on success 725 * -EINVAL if the input parameters' memory are not allocated, 726 * or message type or instance in request header is invalid 727 * -ENOMSG if the PLDM type in the request header is invalid 728 * -EOVERFLOW if the input message length is invalid 729 */ 730 int encode_pldm_base_multipart_receive_req( 731 uint8_t instance_id, const struct pldm_base_multipart_receive_req *req, 732 struct pldm_msg *msg, size_t *payload_length); 733 734 /** @brief Decode a PLDM MultipartReceive response message 735 * 736 * @param[in] msg - Response message 737 * @param[in] payload_length - length of request message payload 738 * @param[out] resp - pointer to the decoded response message, 739 * excluding the data integrity checksum 740 * @param[out] data_integrity_checksum - The checksum of data field 741 * of the decoded response message 742 * @return 0 on success 743 * -EINVAL if the input parameters' memory are not allocated 744 * -EOVERFLOW if the input message buffer is too short for the output 745 * response struct 746 * -EBADMSG if the input message buffer is too large for the output 747 * response struct 748 * @note Caller is responsible for memory alloc and dealloc of param 749 * 'msg.payload' 750 */ 751 int decode_pldm_base_multipart_receive_resp( 752 const struct pldm_msg *msg, size_t payload_length, 753 struct pldm_base_multipart_receive_resp *resp, 754 uint32_t *data_integrity_checksum); 755 756 /** @brief Encode a PLDM MultipartReceive response message 757 * 758 * @param[in] instance_id - Message's instance id 759 * @param[in] resp - The pointer to the response message to be encoded 760 * @param[in] checksum - Checksum of the entirely data payload 761 * @param[in,out] msg - Message will be written to this 762 * @param[in,out] payload_length - length of request message payload 763 * @return 0 on success 764 * -EINVAL if argument values are invalid for the invocation 765 * -ENOMSG if the PLDM type in the request header is invalid 766 * -EOVERFLOW if the input message length is invalid 767 * @note Caller is responsible for memory alloc and dealloc of param 768 * 'msg.payload' 769 */ 770 int encode_base_multipart_receive_resp( 771 uint8_t instance_id, 772 const struct pldm_base_multipart_receive_resp *resp, uint32_t checksum, 773 struct pldm_msg *msg, size_t *payload_length); 774 775 /** @brief Create a PLDM response message containing only cc 776 * 777 * @param[in] instance_id - Message's instance id 778 * @param[in] type - PLDM Type 779 * @param[in] command - PLDM Command 780 * @param[in] cc - PLDM Completion Code 781 * @param[out] msg - Message will be written to this 782 * @return pldm_completion_codes 783 */ 784 int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command, 785 uint8_t cc, struct pldm_msg *msg); 786 787 /** @brief Create a PLDM message only with the header 788 * 789 * @param[in] msg_type - PLDM message type 790 * @param[in] instance_id - Message's instance id 791 * @param[in] pldm_type - PLDM Type 792 * @param[in] command - PLDM Command 793 * @param[out] msg - Message will be written to this 794 * 795 * @return pldm_completion_codes 796 */ 797 int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id, 798 uint8_t pldm_type, uint8_t command, 799 struct pldm_msg *msg); 800 801 /** @brief Encode a PLDM Negotiate Transfer Parameters request message 802 * 803 * @param[in] instance_id - Message's instance id 804 * @param[in] req - The pointer to the request message to be encoded 805 * @param[in,out] msg - Message will be written to this 806 * @param[in, out] payload_length - length of request message payload 807 * @return 0 on success 808 * -EINVAL if the input parameters' memory are not allocated, 809 * or message type or instance in request header is invalid 810 * -ENOMSG if the PLDM type in the request header is invalid 811 * -EOVERFLOW if the input message length is invalid 812 */ 813 int encode_pldm_base_negotiate_transfer_params_req( 814 uint8_t instance_id, 815 const struct pldm_base_negotiate_transfer_params_req *req, 816 struct pldm_msg *msg, size_t *payload_length); 817 818 /** @brief Encode a PLDM Negotiate Transfer Parameters response message 819 * 820 * @param[in] instance_id - Message's instance id 821 * @param[in] resp - The pointer to the response message to be encoded 822 * @param[out] msg - Message will be written to this 823 * @param[in,out] payload_length - length of response message payload 824 * @return 0 on success 825 * -EINVAL if the input parameters' memory are not allocated, 826 * or message type or instance in request header is invalid 827 * -ENOMSG if the PLDM type in the request header is invalid 828 * -EOVERFLOW if the input message length is invalid 829 */ 830 int encode_pldm_base_negotiate_transfer_params_resp( 831 uint8_t instance_id, 832 const struct pldm_base_negotiate_transfer_params_resp *resp, 833 struct pldm_msg *msg, size_t *payload_length); 834 835 /** @brief Decode a PLDM Negotiate Transfer Parameters request message 836 * 837 * @param[in] msg - Request message 838 * @param[in] payload_length - length of request message payload 839 * @param[out] req - pointer to the decoded request message 840 * @return 0 on success 841 * -EINVAL if the input parameters' memory are not allocated 842 * -EOVERFLOW if the input message buffer is too short for the output 843 * request struct 844 * -EBADMSG if the input message buffer is too large for the output 845 * request struct 846 * @note Caller is responsible for memory alloc and dealloc of param 847 * 'msg.payload' 848 */ 849 int decode_pldm_base_negotiate_transfer_params_req( 850 const struct pldm_msg *msg, size_t payload_length, 851 struct pldm_base_negotiate_transfer_params_req *req); 852 853 /** @brief Decode a PLDM Negotiate Transfer Parameters response message 854 * 855 * @param[in] msg - Response message 856 * @param[in] payload_length - length of request message payload 857 * @param[out] resp - pointer to the decoded response message, 858 * excluding the data integrity checksum 859 * @return 0 on success 860 * -EINVAL if the input parameters' memory are not allocated 861 * -EOVERFLOW if the input message buffer is too short for the output 862 * response struct 863 * -EBADMSG if the input message buffer is too large for the output 864 * response struct 865 * @note Caller is responsible for memory alloc and dealloc of param 866 * 'msg.payload' 867 */ 868 int decode_pldm_base_negotiate_transfer_params_resp( 869 const struct pldm_msg *msg, size_t payload_length, 870 struct pldm_base_negotiate_transfer_params_resp *resp); 871 872 #ifdef __cplusplus 873 } 874 #endif 875 876 #endif /* BASE_H */ 877