1 #ifndef FRU_H 2 #define FRU_H 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 #include <asm/byteorder.h> 9 #include <stddef.h> 10 #include <stdint.h> 11 12 #include "base.h" 13 #include "utils.h" 14 15 #define PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES 0 16 #define PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES 19 17 #define PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES 5 18 #define PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES 6 19 #define PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES 6 20 #define PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES 5 21 #define PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES 5 22 23 #define FRU_TABLE_CHECKSUM_SIZE 4 24 25 enum pldm_fru_completion_codes { 26 PLDM_FRU_INVALID_DATA_TRANSFER_HANDLE = 0x80, 27 PLDM_FRU_INVALID_TRANSFER_FLAG = 0x82, 28 PLDM_FRU_DATA_INVALID_DATA_INTEGRITY_CHECK = 0x84, 29 PLDM_FRU_DATA_STRUCTURE_TABLE_UNAVAILABLE = 0x85, 30 }; 31 32 /** @brief PLDM FRU commands 33 */ 34 enum pldm_fru_commands { 35 PLDM_GET_FRU_RECORD_TABLE_METADATA = 0X01, 36 PLDM_GET_FRU_RECORD_TABLE = 0X02, 37 PLDM_SET_FRU_RECORD_TABLE = 0X03, 38 PLDM_GET_FRU_RECORD_BY_OPTION = 0X04 39 }; 40 41 /** @brief FRU record types 42 */ 43 enum pldm_fru_record_type { 44 PLDM_FRU_RECORD_TYPE_GENERAL = 0X01, 45 PLDM_FRU_RECORD_TYPE_OEM = 0XFE, 46 }; 47 48 /** @brief Encoding type for FRU fields 49 */ 50 enum pldm_fru_field_encoding { 51 PLDM_FRU_ENCODING_UNSPECIFIED = 0X00, 52 PLDM_FRU_ENCODING_ASCII = 0X01, 53 PLDM_FRU_ENCODING_UTF8 = 0X02, 54 PLDM_FRU_ENCODING_UTF16 = 0X03, 55 PLDM_FRU_ENCODING_UTF16LE = 0X04, 56 PLDM_FRU_ENCODING_UTF16BE = 0X05, 57 }; 58 59 /** @brief FRU field types 60 */ 61 enum pldm_fru_field_type { 62 PLDM_FRU_FIELD_TYPE_CHASSIS = 0X01, 63 PLDM_FRU_FIELD_TYPE_MODEL = 0X02, 64 PLDM_FRU_FIELD_TYPE_PN = 0X03, 65 PLDM_FRU_FIELD_TYPE_SN = 0X04, 66 PLDM_FRU_FIELD_TYPE_MANUFAC = 0X05, 67 PLDM_FRU_FIELD_TYPE_MANUFAC_DATE = 0X06, 68 PLDM_FRU_FIELD_TYPE_VENDOR = 0X07, 69 PLDM_FRU_FIELD_TYPE_NAME = 0X08, 70 PLDM_FRU_FIELD_TYPE_SKU = 0X09, 71 PLDM_FRU_FIELD_TYPE_VERSION = 0X0A, 72 PLDM_FRU_FIELD_TYPE_ASSET_TAG = 0X0B, 73 PLDM_FRU_FIELD_TYPE_DESC = 0X0C, 74 PLDM_FRU_FIELD_TYPE_EC_LVL = 0X0D, 75 PLDM_FRU_FIELD_TYPE_OTHER = 0X0E, 76 PLDM_FRU_FIELD_TYPE_IANA = 0X0F, 77 }; 78 79 /** @struct pldm_get_fru_record_table_metadata_resp 80 * 81 * Structure representing PLDM get FRU table metadata response. 82 */ 83 struct pldm_get_fru_record_table_metadata_resp { 84 uint8_t completion_code; //!< completion code 85 uint8_t fru_data_major_version; //!< The major version of the FRU Record 86 uint8_t fru_data_minor_version; //!< The minor version of the FRU Record 87 uint32_t 88 fru_table_maximum_size; //!< The size of the largest FRU Record data 89 uint32_t fru_table_length; //!< The total length of the FRU Record Table 90 uint16_t total_record_set_identifiers; //!< The total number of FRU 91 //!< Record Data structures 92 uint16_t 93 total_table_records; //!< The total number of records in the table 94 uint32_t 95 checksum; //!< The integrity checksum on the FRU Record Table data 96 } __attribute__((packed)); 97 98 /** @struct pldm_get_fru_record_table_req 99 * 100 * Structure representing PLDM get FRU record table request. 101 */ 102 struct pldm_get_fru_record_table_req { 103 uint32_t data_transfer_handle; 104 uint8_t transfer_operation_flag; 105 } __attribute__((packed)); 106 107 /** @struct pldm_get_fru_record_table_resp 108 * 109 * Structure representing PLDM get FRU record table response. 110 */ 111 struct pldm_get_fru_record_table_resp { 112 uint8_t completion_code; 113 uint32_t next_data_transfer_handle; 114 uint8_t transfer_flag; 115 uint8_t fru_record_table_data[1]; 116 } __attribute__((packed)); 117 118 struct pldm_get_fru_record_by_option_req { 119 uint32_t data_transfer_handle; 120 uint16_t fru_table_handle; 121 uint16_t record_set_identifier; 122 uint8_t record_type; 123 uint8_t field_type; 124 uint8_t transfer_op_flag; 125 } __attribute__((packed)); 126 127 struct pldm_get_fru_record_by_option_resp { 128 uint8_t completion_code; 129 uint32_t next_data_transfer_handle; 130 uint8_t transfer_flag; 131 uint8_t fru_structure_data[1]; 132 } __attribute__((packed)); 133 134 struct pldm_set_fru_record_table_req { 135 uint32_t data_transfer_handle; 136 uint8_t transfer_flag; 137 uint8_t fru_record_table_data[1]; 138 } __attribute__((packed)); 139 140 struct pldm_set_fru_record_table_resp { 141 uint8_t completion_code; 142 uint32_t next_data_transfer_handle; 143 } __attribute__((packed)); 144 145 /** @struct pldm_fru_record_tlv 146 * 147 * Structure representing each FRU field entry (type, length, value) 148 */ 149 struct pldm_fru_record_tlv { 150 uint8_t type; 151 uint8_t length; 152 uint8_t value[1]; 153 } __attribute__((packed)); 154 155 /** @struct pldm_fru_record_data_format 156 * 157 * Structure representing the FRU record data format 158 */ 159 struct pldm_fru_record_data_format { 160 uint16_t record_set_id; 161 uint8_t record_type; 162 uint8_t num_fru_fields; 163 uint8_t encoding_type; 164 struct pldm_fru_record_tlv tlvs[1]; 165 } __attribute__((packed)); 166 167 /* Requester */ 168 169 /* GetFRURecordTableMetadata */ 170 171 /** @brief Create a PLDM request message for GetFRURecordTableMetadata 172 * 173 * @param[in] instance_id - Message's instance id 174 * @param[in,out] msg - Message will be written to this 175 * @param[in] payload_length - Length of the request message payload 176 * @return pldm_completion_codes 177 * @note Caller is responsible for memory alloc and dealloc of param 178 * 'msg.payload' 179 */ 180 int encode_get_fru_record_table_metadata_req(uint8_t instance_id, 181 struct pldm_msg *msg, 182 size_t payload_length); 183 184 /** @brief Decode GetFruRecordTable response data 185 * 186 * Note: 187 * * If the return value is not PLDM_SUCCESS, it represents a 188 * transport layer error. 189 * * If the completion_code value is not PLDM_SUCCESS, it represents a 190 * protocol layer error and all the out-parameters are invalid. 191 * 192 * @param[in] msg - Response message 193 * @param[in] payload_length - Length of response message payload 194 * @param[out] completion_code - Pointer to response msg's PLDM completion code 195 * @param[out] fru_data_major_version - Major version of the FRU Record 196 * @param[out] fru_data_minor_version - Minor version of the FRU Record 197 * @param[out] fru_table_maximum_size - Size of the largest FRU Record data 198 * @param[out] fru_table_length - Total length of the FRU Record Table 199 * @param[out] total_Record_Set_Identifiers - Total number of FRU Record Data 200 * structures 201 * @param[out] total_table_records - Total number of records in the table 202 * @param[out] checksum - integrity checksum on the FRU Record Table data 203 * @return pldm_completion_codes 204 */ 205 int decode_get_fru_record_table_metadata_resp( 206 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code, 207 uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version, 208 uint32_t *fru_table_maximum_size, uint32_t *fru_table_length, 209 uint16_t *total_record_set_identifiers, uint16_t *total_table_records, 210 uint32_t *checksum); 211 212 /* Responder */ 213 214 /* GetFRURecordTableMetadata */ 215 216 /** @brief Create a PLDM response message for GetFRURecordTableMetadata 217 * 218 * @param[in] instance_id - Message's instance id 219 * @param[in] completion_code - PLDM completion code 220 * @param[in] fru_data_major_version - Major version of the FRU Record 221 * @param[in] fru_data_minor_version - Minor version of the FRU Record 222 * @param[in] fru_table_maximum_size - Size of the largest FRU Record data 223 * @param[in] fru_table_length - Total length of the FRU Record Table 224 * @param[in] total_Record_Set_Identifiers - Total number of FRU Record Data 225 * structures 226 * @param[in] total_table_records - Total number of records in the table 227 * @param[in] checksum - integrity checksum on the FRU Record Table data 228 * @param[in,out] msg - Message will be written to this 229 * @return pldm_completion_codes 230 * @note Caller is responsible for memory alloc and dealloc of param 231 * 'msg.payload' 232 */ 233 234 int encode_get_fru_record_table_metadata_resp( 235 uint8_t instance_id, uint8_t completion_code, 236 uint8_t fru_data_major_version, uint8_t fru_data_minor_version, 237 uint32_t fru_table_maximum_size, uint32_t fru_table_length, 238 uint16_t total_record_set_identifiers, uint16_t total_table_records, 239 uint32_t checksum, struct pldm_msg *msg); 240 241 /* GetFruRecordTable */ 242 243 /** @brief Decode GetFruRecordTable request data 244 * 245 * @param[in] msg - PLDM request message payload 246 * @param[in] payload_length - Length of request payload 247 * @param[out] data_transfer_handle - A handle, used to identify a FRU Record 248 * Table data transfer 249 * @param[out] transfer_operation_flag - A flag that indicates whether this is 250 * the start of the transfer 251 * @return pldm_completion_codes 252 */ 253 int decode_get_fru_record_table_req(const struct pldm_msg *msg, 254 size_t payload_length, 255 uint32_t *data_transfer_handle, 256 uint8_t *transfer_operation_flag); 257 258 /** @brief Create a PLDM response message for GetFruRecordTable 259 * 260 * @param[in] instance_id - Message's instance id 261 * @param[in] completion_code - PLDM completion code 262 * @param[in] next_data_transfer_handle - A handle that is used to identify the 263 * next portion of the transfer 264 * @param[in] transfer_flag - The transfer flag that indicates what part of the 265 * transfer this response represents 266 * @param[in,out] msg - Message will be written to this 267 * @return pldm_completion_codes 268 * @note Caller is responsible for memory alloc and dealloc of param 'msg', 269 * and for appending the FRU table to the msg. 270 */ 271 int encode_get_fru_record_table_resp(uint8_t instance_id, 272 uint8_t completion_code, 273 uint32_t next_data_transfer_handle, 274 uint8_t transfer_flag, 275 struct pldm_msg *msg); 276 277 /* GetFRURecordByOption */ 278 279 /** @brief Decode GetFRURecordByOption request data 280 * 281 * @param[in] msg - PLDM request message payload 282 * @param[in] payload_length - Length of request payload 283 * @param[out] data_transfer_handle - A handle, used to identify a FRU Record 284 * Table data transfer 285 * @param[out] fru_table_handle - A handle, used to identify a FRU DATA 286 * records 287 * @param[out] record_set_identifier - FRU record set identifier 288 * @param[out] record_type - FRU record type 289 * @param[out] field_type - FRU field type 290 * @param[out] transfer_op_flag - A flag that indicates whether this is 291 * the start of the transfer 292 * @return pldm_completion_codes 293 */ 294 int decode_get_fru_record_by_option_req( 295 const struct pldm_msg *msg, size_t payload_length, 296 uint32_t *data_transfer_handle, uint16_t *fru_table_handle, 297 uint16_t *record_set_identifier, uint8_t *record_type, uint8_t *field_type, 298 uint8_t *transfer_op_flag); 299 300 /** @brief Encode GetFRURecordByOption response data 301 * 302 * @param[in] instance_id - Message's instance id 303 * @param[in] completion_code - PLDM completion code 304 * @param[in] next_data_transfer_handle - A handle that is used to identify the 305 * next portion of the transfer 306 * @param[in] transfer_flag - The transfer flag that indicates what part of the 307 * transfer this response represents 308 * @param[in] fru_structure_data - FRU Structure Data 309 * @param[in] data_size - Size of FRU Structrue Data 310 * @param[in,out] msg - Message will be written to this 311 * @return pldm_completion_codes 312 * @note Caller is responsible for memory alloc and dealloc of param 'msg', 313 * and for appending the FRU table to the msg. 314 */ 315 int encode_get_fru_record_by_option_resp(uint8_t instance_id, 316 uint8_t completion_code, 317 uint32_t next_data_transfer_handle, 318 uint8_t transfer_flag, 319 const void *fru_structure_data, 320 size_t data_size, struct pldm_msg *msg, 321 size_t payload_length); 322 323 /* Requester */ 324 325 /* GetFruRecordTable */ 326 327 /** @brief Create a PLDM request message for GetFruRecordTable 328 * 329 * @param[in] instance_id - Message's instance id 330 * @param[in] data_transfer_handle - A handle, used to identify a FRU Record 331 * Table data transfer 332 * @param[in] transfer_operation_flag - A flag that indicates whether this is 333 * the start of the transfer 334 * @param[in,out] msg - Message will be written to this 335 * @param[in] payload_length - Length of request message payload 336 * @return pldm_completion_codes 337 * @note Caller is responsible for memory alloc and dealloc of param 338 * 'msg.payload' 339 */ 340 341 int encode_get_fru_record_table_req(uint8_t instance_id, 342 uint32_t data_transfer_handle, 343 uint8_t transfer_operation_flag, 344 struct pldm_msg *msg, 345 size_t payload_length); 346 347 /** @brief Decode GetFruRecordTable response data 348 * 349 * @param[in] msg - Response message 350 * @param[in] payload_length - Length of response message payload 351 * @param[out] completion_code - Pointer to response msg's PLDM completion code 352 * @param[out] next_data_transfer_handle - A handle used to identify the next 353 * portion of the transfer 354 * @param[out] transfer_flag - The transfer flag that indicates what part of 355 * the transfer this response represents 356 * @param[out] fru_record_table_data - This data is a portion of the overall 357 * FRU Record Table 358 * @param[out] fru_record_table_length - Length of the FRU record table data 359 * @return pldm_completion_codes 360 */ 361 362 int decode_get_fru_record_table_resp( 363 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code, 364 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 365 uint8_t *fru_record_table_data, size_t *fru_record_table_length); 366 367 /** @brief Decode GetFruRecordTable response data, ensuring that the fru 368 * record table section is small enough to fit in the provided buffer. 369 * 370 * @param[in] msg - Response message 371 * @param[in] payload_length - Length of response message payload 372 * @param[out] completion_code - Pointer to response msg's PLDM completion code 373 * @param[out] next_data_transfer_handle - A handle used to identify the next 374 * portion of the transfer 375 * @param[out] transfer_flag - The transfer flag that indicates what part of 376 * the transfer this response represents 377 * @param[out] fru_record_table_data - This data is a portion of the overall 378 * FRU Record Table 379 * @param[out] fru_record_table_length - Length of the FRU record table data 380 * @param[in] max_fru_record_table_length - Maximum length of the FRU record 381 * table data. If the response contains more data than this, 382 * return PLDM_ERROR_INVALID_LENGTH. 383 * @return pldm_completion_codes 384 */ 385 386 int decode_get_fru_record_table_resp_safe( 387 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code, 388 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 389 uint8_t *fru_record_table_data, size_t *fru_record_table_length, 390 size_t max_fru_record_table_length); 391 392 /** @brief Encode the FRU record in the FRU table 393 * 394 * @param[in/out] fru_table - Pointer to the FRU table 395 * @param[in] total_size - The size of the table,including the size of FRU 396 * record to be added to the table. 397 * @param[in/out] curr_size - The size of the table, excluding the size of FRU 398 * record to be added to the table. 399 * @param[in] record_set_id - FRU record set identifier 400 * @param[in] record_type - FRU record type 401 * @param[in] num_frus - Number of FRU fields 402 * @param[in] encoding - Encoding type for FRU fields 403 * @param[in] tlvs - Pointer to the buffer with all the FRU fields 404 * @param[in] tlvs_size - Size of the buffer with all the FRU fields 405 * 406 * @return pldm_completion_codes 407 */ 408 int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size, 409 uint16_t record_set_id, uint8_t record_type, 410 uint8_t num_frus, uint8_t encoding, uint8_t *tlvs, 411 size_t tlvs_size); 412 413 /* GetFRURecordByOption */ 414 415 /** @brief Create a PLDM request message for GetFRURecordByOption 416 * 417 * @param[in] instance_id - Message's instance id 418 * @param[in] data_transfer_handle - A handle, used to identify a FRU Record 419 * Table data transfer 420 * @param[in] fru_table_handle - A handle, used to identify a FRU DATA records 421 * @param[in] record_set_identifier - FRU record set identifier 422 * @param[in] record_type - FRU record type 423 * @param[in] field_type - FRU field type 424 * @param[in] transfer_op_flag - A flag that indicates whether this is 425 * the start of the transfer 426 * @param[in,out] msg - Message will be written to this 427 * @param[in] payload_length - Length of request message payload 428 * @return pldm_completion_codes 429 * @note Caller is responsible for memory alloc and dealloc of param 430 * 'msg.payload' 431 */ 432 int encode_get_fru_record_by_option_req( 433 uint8_t instance_id, uint32_t data_transfer_handle, 434 uint16_t fru_table_handle, uint16_t record_set_identifier, 435 uint8_t record_type, uint8_t field_type, uint8_t transfer_op_flag, 436 struct pldm_msg *msg, size_t payload_length); 437 438 /** @brief Decode GetFRURecordByOption response data 439 * 440 * @param[in] msg - Response message 441 * @param[in] payload_length - Length of response message payload 442 * @param[out] completion_code - Pointer to response msg's PLDM completion code 443 * @param[out] next_data_transfer_handle - A handle used to identify the next 444 * portion of the transfer 445 * @param[out] transfer_flag - The transfer flag that indicates what part of 446 * the transfer this response represents 447 * @param[out] fru_structure_data - FRU Structure Data 448 * @return pldm_completion_codes 449 */ 450 int decode_get_fru_record_by_option_resp( 451 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code, 452 uint32_t *next_transfer_handle, uint8_t *transfer_flag, 453 struct variable_field *fru_structure_data); 454 455 /** @brief Get FRU Record Table By Option 456 * @param[in] table - The source fru record table 457 * @param[in] table_size - Size of the source fru record table 458 * @param[out] record_table - Fru table fetched based on the input option 459 * @param[in/out] record_size - Size of the table fetched by fru record option 460 * @param[in] rsi - FRU record set identifier 461 * @param[in] rt - FRU record type 462 * @param[in] ft - FRU field type 463 */ 464 void get_fru_record_by_option(const uint8_t *table, size_t table_size, 465 uint8_t *record_table, size_t *record_size, 466 uint16_t rsi, uint8_t rt, uint8_t ft); 467 /* SetFruRecordTable */ 468 469 /** @brief Decode SetFruRecordTable request data 470 * 471 * @param[in] msg - PLDM request message payload 472 * @param[in] payload_length - Length of request payload 473 * @param[out] data_transfer_handle - A handle used to identify a FRU Record 474 * table data transfer 475 * @param[out] transfer_flag - Flag to indicate what part of the transfer 476 * this request represents 477 * @param[out] fru_table_data - Struct variable_field, contains data specific 478 * to the fru record table and the length of table 479 * data 480 * @return pldm_completion_codes 481 */ 482 int decode_set_fru_record_table_req(const struct pldm_msg *msg, 483 size_t payload_length, 484 uint32_t *data_transfer_handle, 485 uint8_t *transfer_flag, 486 struct variable_field *fru_table_data); 487 488 /** @brief Create a PLDM response message for SetFruRecordTable 489 * 490 * @param[in] instance_id - Message's instance id 491 * @param[in] completion_code - PLDM completion code 492 * @param[in] next_transfer_handle - handle to identify the next portion of the 493 * transfer 494 * @param[in] payload_length - Length of payload message 495 * @param[out] msg - Argument to capture the Message 496 */ 497 int encode_set_fru_record_table_resp(uint8_t instance_id, 498 uint8_t completion_code, 499 uint32_t next_data_transfer_handle, 500 size_t payload_length, 501 struct pldm_msg *msg); 502 503 #ifdef __cplusplus 504 } 505 #endif 506 507 #endif 508