1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 #ifndef PDR_H 3 #define PDR_H 4 5 #ifdef __cplusplus 6 extern "C" { 7 #endif 8 9 #include <stdbool.h> 10 #include <stddef.h> 11 #include <stdint.h> 12 13 /** @struct pldm_pdr 14 * opaque structure that acts as a handle to a PDR repository 15 */ 16 typedef struct pldm_pdr pldm_pdr; 17 18 /** @struct pldm_pdr_record 19 * opaque structure that acts as a handle to a PDR record 20 */ 21 typedef struct pldm_pdr_record pldm_pdr_record; 22 23 /* ====================== */ 24 /* Common PDR access APIs */ 25 /* ====================== */ 26 27 /** @brief Make a new PDR repository 28 * 29 * @return opaque pointer that acts as a handle to the repository; NULL if no 30 * repository could be created 31 * 32 * @note Caller may make multiple repositories (for its own PDRs, as well as 33 * for PDRs received by other entities) and can associate the returned handle 34 * to a PLDM terminus id. 35 */ 36 pldm_pdr *pldm_pdr_init(void); 37 38 /** @brief Destroy a PDR repository (and free up associated resources) 39 * 40 * @param[in/out] repo - pointer to opaque pointer acting as a PDR repo handle 41 */ 42 void pldm_pdr_destroy(pldm_pdr *repo); 43 44 /** @brief Get number of records in a PDR repository 45 * 46 * @pre repo must point to a valid object 47 * 48 * @param[in] repo - opaque pointer acting as a PDR repo handle 49 * 50 * @return uint32_t - number of records 51 */ 52 uint32_t pldm_pdr_get_record_count(const pldm_pdr *repo); 53 54 /** @brief Get size of a PDR repository, in bytes 55 * 56 * @pre repo must point to a valid object 57 * 58 * @param[in] repo - opaque pointer acting as a PDR repo handle 59 * 60 * @return uint32_t - size in bytes 61 */ 62 uint32_t pldm_pdr_get_repo_size(const pldm_pdr *repo); 63 64 /** @brief Add a PDR record to a PDR repository, or return an error 65 * 66 * @param[in/out] repo - opaque pointer acting as a PDR repo handle 67 * @param[in] data - pointer to a PDR record, pointing to a PDR definition as 68 * per DSP0248. This data is memcpy'd. 69 * @param[in] size - size of input PDR record in bytes 70 * @param[in] is_remote - if true, then the PDR is not from this terminus 71 * @param[in] terminus_handle - terminus handle of the input PDR record 72 * @param[in,out] record_handle - record handle of input PDR record. If this is set to 0 then a 73 * record handle is computed. The computed handle is assigned to both the PDR record and back into 74 * record_handle for the caller to consume. 75 * 76 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 77 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 78 */ 79 int pldm_pdr_add(pldm_pdr *repo, const uint8_t *data, uint32_t size, 80 bool is_remote, uint16_t terminus_handle, 81 uint32_t *record_handle); 82 83 /** @brief Get record handle of a PDR record 84 * 85 * @pre repo must point to a valid object 86 * @pre record must point to a valid object 87 * 88 * @param[in] repo - opaque pointer acting as a PDR repo handle 89 * @param[in] record - opaque pointer acting as a PDR record handle 90 * 91 * @return uint32_t - record handle assigned to PDR record; 0 if record is not 92 * found 93 */ 94 uint32_t pldm_pdr_get_record_handle(const pldm_pdr *repo, 95 const pldm_pdr_record *record); 96 97 /** @brief Get terminus handle of a PDR record 98 * 99 * @pre repo must point to a valid object 100 * @pre record must point to a valid object 101 * 102 * @param[in] repo - opaque pointer acting as a PDR repo handle 103 * @param[in] reocrd - opaque pointer acting as a PDR record handle 104 * 105 * @return uint16_t - terminus handle assigned to PDR record 106 */ 107 uint16_t pldm_pdr_get_terminus_handle(const pldm_pdr *repo, 108 const pldm_pdr_record *record); 109 110 /** @brief Find PDR record by record handle 111 * 112 * @param[in] repo - opaque pointer acting as a PDR repo handle 113 * @param[in] record_handle - input record handle 114 * @param[in/out] data - will point to PDR record data (as per DSP0248) on 115 * return 116 * @param[out] size - *size will be size of PDR record 117 * @param[out] next_record_handle - *next_record_handle will be the record 118 * handle of record next to the returned PDR record 119 * 120 * @return opaque pointer acting as PDR record handle, will be NULL if record 121 * was not found 122 */ 123 const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo, 124 uint32_t record_handle, 125 uint8_t **data, uint32_t *size, 126 uint32_t *next_record_handle); 127 128 /** @brief Get PDR record next to input PDR record 129 * 130 * @param[in] repo - opaque pointer acting as a PDR repo handle 131 * @param[in] curr_record - opaque pointer acting as a PDR record handle 132 * @param[in/out] data - will point to PDR record data (as per DSP0248) on 133 * return 134 * @param[out] size - *size will be size of PDR record 135 * @param[out] next_record_handle - *next_record_handle will be the record 136 * handle of record nect to the returned PDR record 137 * 138 * @return opaque pointer acting as PDR record handle, will be NULL if record 139 * was not found 140 */ 141 const pldm_pdr_record * 142 pldm_pdr_get_next_record(const pldm_pdr *repo, 143 const pldm_pdr_record *curr_record, uint8_t **data, 144 uint32_t *size, uint32_t *next_record_handle); 145 146 /** @brief Find (first) PDR record by PDR type 147 * 148 * @param[in] repo - opaque pointer acting as a PDR repo handle 149 * @param[in] pdr_type - PDR type number as per DSP0248 150 * @param[in] curr_record - opaque pointer acting as a PDR record handle; if 151 * not NULL, then search will begin from this record's next record 152 * @param[in/out] data - will point to PDR record data (as per DSP0248) on 153 * return, if input is not NULL 154 * @param[out] size - *size will be size of PDR record, if input is not NULL 155 * 156 * @return opaque pointer acting as PDR record handle, will be NULL if record 157 * was not found 158 */ 159 const pldm_pdr_record * 160 pldm_pdr_find_record_by_type(const pldm_pdr *repo, uint8_t pdr_type, 161 const pldm_pdr_record *curr_record, uint8_t **data, 162 uint32_t *size); 163 164 /** @brief Determine if a record is a remote record 165 * 166 * @pre record must point to a valid object 167 * 168 * @return true if the record is a remote record, false otherwise. 169 */ 170 bool pldm_pdr_record_is_remote(const pldm_pdr_record *record); 171 172 /** @brief Remove all PDR records that belong to a remote terminus 173 * 174 * @param[in] repo - opaque pointer acting as a PDR repo handle 175 * 176 * If repo is NULL then there are no PDRs that can be removed. 177 */ 178 void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo); 179 180 /** @brief Remove all remote PDR's that belong to a specific terminus 181 * handle 182 * @param[in] repo - opaque pointer acting as a PDR repo handle 183 * @param[in] terminus_handle - Terminus Handle of the remove PLDM terminus 184 * 185 * If repo is NULL there are no PDRs that can be removed. 186 */ 187 void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo, 188 uint16_t terminus_handle); 189 190 /** @brief Update the validity of TL PDR - the validity is decided based on 191 * whether the valid bit is set or not as per the spec DSP0248 192 * 193 * @param[in] repo - opaque pointer acting as a PDR repo handle 194 * @param[in] terminus_handle - PLDM terminus handle 195 * @param[in] tid - Terminus ID 196 * @param[in] tl_eid - MCTP endpoint EID 197 * @param[in] valid - validity bit of TLPDR 198 */ 199 /* NOLINTNEXTLINE(readability-identifier-naming) */ 200 void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminus_handle, 201 uint8_t tid, uint8_t tl_eid, bool valid); 202 203 /** @brief Find the last record within the particular range 204 * of record handles 205 * 206 * @param[in] repo - pointer acting as a PDR repo handle 207 * @param[in] first - first record handle value of the records in the range 208 * @param[in] last - last record handle value of the records in the range 209 * 210 * @return pointer to the PDR record,will be NULL if record was not 211 * found 212 */ 213 pldm_pdr_record *pldm_pdr_find_last_in_range(const pldm_pdr *repo, 214 uint32_t first, uint32_t last); 215 216 /** @brief find the container ID of the contained entity which is not in the 217 * particular range of record handles given 218 * 219 * @param[in] repo - opaque pointer acting as a PDR repo handle 220 * @param[in] entity_type - entity type 221 * @param[in] entity_instance - instance of the entity 222 * @param[in] child_index - index of the child entity whose container id needs to be found 223 * @param[in] range_exclude_start_handle - first record handle in the range of the remote endpoint 224 * which is ignored 225 * @param[in] range_exclude_end_handle - last record handle in the range of the remote endpoint 226 * which is ignored 227 * @param[out] container_id - container id of the contained entity 228 * 229 * @return container id of the PDR record found on success,-EINVAL when repo is NULL 230 * or -ENOENT if the container id is not found. 231 */ 232 int pldm_pdr_find_child_container_id_index_range_exclude( 233 const pldm_pdr *repo, uint16_t entity_type, uint16_t entity_instance, 234 uint8_t child_index, uint32_t range_exclude_start_handle, 235 uint32_t range_exclude_end_handle, uint16_t *container_id); 236 237 /* ======================= */ 238 /* FRU Record Set PDR APIs */ 239 /* ======================= */ 240 241 /** @brief Add a FRU record set PDR record to a PDR repository, or return an error 242 * 243 * @param[in/out] repo - opaque pointer acting as a PDR repo handle 244 * @param[in] terminus_handle - PLDM terminus handle of terminus owning the PDR 245 * record 246 * @param[in] fru_rsi - FRU record set identifier 247 * @param[in] entity_type - entity type of FRU 248 * @param[in] entity_instance_num - entity instance number of FRU 249 * @param[in] container_id - container id of FRU 250 * @param[in,out] bmc_record_handle - A pointer to the handle used to construct the next record. If 251 * the value is zero on input then a new handle is automatically allocated. 252 * Otherwise, the provided handle is used. If a new handle is automatically 253 * allocated then the object pointed to by bmc_record_handle will contain its value 254 * as output. 255 * @return 0 on success, -EINVAL if the arguments are invalid, or -ENOMEM if an internal allocation 256 * fails. 257 */ 258 int pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle, 259 uint16_t fru_rsi, uint16_t entity_type, 260 uint16_t entity_instance_num, 261 uint16_t container_id, 262 uint32_t *bmc_record_handle); 263 264 /** @brief Find a FRU record set PDR by FRU record set identifier 265 * 266 * @param[in] repo - opaque pointer acting as a PDR repo handle 267 * @param[in] fru_rsi - FRU record set identifier 268 * @param[in] terminus_handle - *terminus_handle will be FRU terminus handle of 269 * found PDR, or 0 if not found 270 * @param[in] entity_type - *entity_type will be FRU entity type of found PDR, 271 * or 0 if not found 272 * @param[in] entity_instance_num - *entity_instance_num will be FRU entity 273 * instance number of found PDR, or 0 if not found 274 * @param[in] container_id - *cintainer_id will be FRU container id of found 275 * PDR, or 0 if not found 276 * 277 * @return An opaque pointer to the PDR record on success, or NULL on failure 278 */ 279 const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( 280 const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle, 281 uint16_t *entity_type, uint16_t *entity_instance_num, 282 uint16_t *container_id); 283 284 /* =========================== */ 285 /* Entity Association PDR APIs */ 286 /* =========================== */ 287 288 typedef struct pldm_entity { 289 uint16_t entity_type; 290 uint16_t entity_instance_num; 291 uint16_t entity_container_id; 292 } __attribute__((packed)) pldm_entity; 293 294 enum entity_association_containment_type { 295 PLDM_ENTITY_ASSOCIAION_PHYSICAL = 0x0, 296 PLDM_ENTITY_ASSOCIAION_LOGICAL = 0x1, 297 }; 298 299 /** @struct pldm_entity_association_tree 300 * opaque structure that represents the entity association hierarchy 301 */ 302 typedef struct pldm_entity_association_tree pldm_entity_association_tree; 303 304 /** @struct pldm_entity_node 305 * opaque structure that represents a node in the entity association hierarchy 306 */ 307 typedef struct pldm_entity_node pldm_entity_node; 308 309 /** @brief Make a new entity association tree 310 * 311 * @return opaque pointer that acts as a handle to the tree; NULL if no 312 * tree could be created 313 */ 314 pldm_entity_association_tree *pldm_entity_association_tree_init(void); 315 316 /** @brief Add a local entity into the entity association tree 317 * 318 * @param[in/out] tree - opaque pointer acting as a handle to the tree 319 * @param[in/out] entity - pointer to the entity to be added. Input has the 320 * entity type. On output, instance number and the 321 * container id are populated. 322 * @param[in] entity_instance_number - entity instance number, we can use the 323 * entity instance number of the entity by 324 * default if its value is equal 0xffff. 325 * @param[in] parent - pointer to the node that should be the parent of input 326 * entity. If this is NULL, then the entity is the root 327 * @param[in] association_type - relation with the parent : logical or physical 328 * 329 * @return pldm_entity_node* - opaque pointer to added entity 330 */ 331 pldm_entity_node *pldm_entity_association_tree_add( 332 pldm_entity_association_tree *tree, pldm_entity *entity, 333 uint16_t entity_instance_number, pldm_entity_node *parent, 334 uint8_t association_type); 335 336 /** @brief Add an entity into the entity association tree based on remote field 337 * set or unset. 338 * 339 * @param[in/out] tree - opaque pointer acting as a handle to the tree 340 * @param[in/out] entity - pointer to the entity to be added. Input has the 341 * entity type. On output, instance number and the 342 * container id are populated. 343 * @param[in] entity_instance_number - entity instance number, we can use the 344 * entity instance number of the entity by 345 * default if its value is equal 0xffff. 346 * @param[in] parent - pointer to the node that should be the parent of input 347 * entity. If this is NULL, then the entity is the root 348 * @param[in] association_type - relation with the parent : logical or physical 349 * @param[in] is_remote - used to denote whether we are adding a BMC entity to 350 * the tree or a host entity 351 * @param[in] is_update_contanier_id - Used to determine whether need to update 352 * contanier id. 353 * true: should be changed 354 * false: should not be changed 355 * @param[in] container_id - container id of the entity added. 356 * 357 * @return pldm_entity_node* - opaque pointer to added entity 358 */ 359 pldm_entity_node *pldm_entity_association_tree_add_entity( 360 pldm_entity_association_tree *tree, pldm_entity *entity, 361 uint16_t entity_instance_number, pldm_entity_node *parent, 362 uint8_t association_type, bool is_remote, bool is_update_container_id, 363 uint16_t container_id); 364 365 /** @brief Visit and note each entity in the entity association tree 366 * 367 * @pre `*entities == NULL` and `*size == 0` must hold at the time of invocation. 368 * 369 * Callers must inspect the values of `*entities` and `*size` post-invocation to determine if the 370 * invocation was a success or failure. 371 * 372 * @param[in] tree - opaque pointer acting as a handle to the tree 373 * @param[out] entities - pointer to list of pldm_entity's. To be free()'d by 374 * the caller 375 * @param[out] size - number of pldm_entity's 376 */ 377 void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree, 378 pldm_entity **entities, size_t *size); 379 380 /** @brief Extract pldm entity by the pldm_entity_node 381 * 382 * @pre node must point to a valid object 383 * 384 * @param[in] node - opaque pointer to added entity 385 * 386 * @return pldm_entity - pldm entity 387 */ 388 pldm_entity pldm_entity_extract(pldm_entity_node *node); 389 390 /** @brief Extract remote container id from the pldm_entity_node 391 * 392 * @pre entity must point to a valid object 393 * 394 * @param[in] entity - pointer to existing entity 395 * 396 * @return The remote container id 397 */ 398 uint16_t 399 pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity); 400 401 /** @brief Destroy entity association tree 402 * 403 * @param[in] tree - opaque pointer acting as a handle to the tree 404 */ 405 void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree); 406 407 /** @brief Check if input entity node is a parent 408 * 409 * @pre node must point to a valid object 410 * 411 * @param[in] node - opaque pointer acting as a handle to an entity node 412 * 413 * @return bool true if node is a parent, false otherwise 414 */ 415 bool pldm_entity_is_node_parent(pldm_entity_node *node); 416 417 /** @brief Get parent of entity 418 * 419 * @pre node must point to a valid object 420 * 421 * @param[in] node - opaque pointer acting as a handle to an entity node 422 * 423 * @return pldm_entity - pldm entity 424 */ 425 pldm_entity pldm_entity_get_parent(pldm_entity_node *node); 426 427 /** @brief Check the current pldm entity is exist parent 428 * 429 * @pre node must point to a valid object 430 * 431 * @param[in] node - opaque pointer acting as a handle to an entity node 432 * 433 * @return bool true if exist parent, false otherwise 434 */ 435 bool pldm_entity_is_exist_parent(pldm_entity_node *node); 436 437 /** @brief Convert entity association tree to PDR, or return an error 438 * 439 * No conversion takes place if one or both of tree or repo are NULL. 440 * 441 * If an error is returned then the state and consistency of the PDR repository is undefined. 442 * 443 * @param[in] tree - opaque pointer to entity association tree 444 * @param[in] repo - PDR repo where entity association records should be added 445 * @param[in] is_remote - if true, then the PDR is not from this terminus 446 * @param[in] terminus_handle - terminus handle of the terminus 447 * 448 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 449 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 450 */ 451 int pldm_entity_association_pdr_add(pldm_entity_association_tree *tree, 452 pldm_pdr *repo, bool is_remote, 453 uint16_t terminus_handle); 454 455 /** @brief Add a contained entity as a remote PDR to an existing entity association PDR. 456 * 457 * Remote PDRs are PDRs added as a child to an entity in the entity association tree and 458 * not to the tree directly. This means remote PDRs have a parent PDR in the entity 459 * association tree to which they are linked. 460 * 461 * @param[in] repo - opaque pointer to pldm PDR repo 462 * @param[in] entity - the contained entity to be added 463 * @param[in] pdr_record_handle - record handle of the container entity to which the remote 464 * PDR is to be added as a child 465 * 466 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 467 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 468 */ 469 int pldm_entity_association_pdr_add_contained_entity_to_remote_pdr( 470 pldm_pdr *repo, pldm_entity *entity, uint32_t pdr_record_handle); 471 472 /** @brief Creates a new entity association PDR with contained entity & its parent. 473 * 474 * @param[in] repo - opaque pointer to pldm PDR repo 475 * @param[in] pdr_record_handle - record handle of the PDR after which the new container 476 * entity has to be added 477 * @param[in] parent - the container entity 478 * @param[in] entity - the contained entity to be added 479 * @param[in-out] entity_record_handle - record handle of a container entity added to the 480 * entity association PDR 481 * 482 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 483 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 484 */ 485 int pldm_entity_association_pdr_create_new(pldm_pdr *repo, 486 uint32_t pdr_record_handle, 487 pldm_entity *parent, 488 pldm_entity *entity, 489 uint32_t *entity_record_handle); 490 491 /** @brief Add entity association pdr from node, or return an error 492 * 493 * @param[in] node - opaque pointer acting as a handle to an entity node 494 * @param[in] repo - PDR repo where entity association records should be added 495 * @param[in] is_remote - if true, then the PDR is not from this terminus 496 * @param[in] terminus_handle - terminus handle of the terminus 497 * 498 * @return 0 on success, -EINVAL if the provided arguments are invalid. 499 */ 500 int pldm_entity_association_pdr_add_from_node( 501 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities, 502 size_t num_entities, bool is_remote, uint16_t terminus_handle); 503 504 /** @brief Add entity association pdr record based on record handle 505 * earlier the records where added in a sequential way alone, with 506 * this change the entity association PDR records gets the new record 507 * handle based on the input value given. 508 * 509 * @param[in] node - opaque pointer acting as a handle to an entity node 510 * @param[in] repo - PDR repo where entity association records should be added 511 * @param[in] is_remote - if true, then the PDR is not from this terminus 512 * @param[in] terminus_handle - terminus handle of the terminus 513 * @param[in] record_handle - record handle of the PDR 514 * 515 * @return 0 on success, -EINVAL if the provided arguments are invalid. 516 */ 517 int pldm_entity_association_pdr_add_from_node_with_record_handle( 518 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities, 519 size_t num_entities, bool is_remote, uint16_t terminus_handle, 520 uint32_t record_handle); 521 522 /** @brief Find entity reference in tree 523 * 524 * @param[in] tree - opaque pointer to entity association tree 525 * @param[in] entity - PLDM entity 526 * @param[in] node - node to the entity 527 */ 528 void pldm_find_entity_ref_in_tree(pldm_entity_association_tree *tree, 529 pldm_entity entity, pldm_entity_node **node); 530 531 /** @brief Get number of children of entity 532 * 533 * @param[in] node - opaque pointer acting as a handle to an entity node 534 * @param[in] association_type - relation type filter : logical or physical 535 * 536 * @return uint8_t number of children. The returned value is zero if node is NULL or 537 * association_type is not one of PLDM_ENTITY_ASSOCIAION_PHYSICAL or 538 * PLDM_ENTITY_ASSOCIAION_LOGICAL. 539 */ 540 uint8_t pldm_entity_get_num_children(pldm_entity_node *node, 541 uint8_t association_type); 542 543 /** @brief Verify that the current node is a child of the current parent 544 * 545 * @pre parent must point to a valid object 546 * @pre node must point to a valid object 547 * 548 * @param[in] parent - opaque pointer acting as a handle to an entity parent 549 * @param[in] node - pointer to the node of the pldm entity 550 * 551 * @return True if the node is a child of parent, false otherwise, including if one or both of 552 * parent or node are NULL. 553 */ 554 bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node); 555 556 /** @brief Find an entity in the entity association tree 557 * 558 * @param[in] tree - pointer to entity association tree 559 * @param[in/out] entity - entity type and instance id set on input, container 560 * id set on output 561 * @return pldm_entity_node* pointer to entity if found, NULL otherwise 562 * 563 * There are no entity nodes to search if tree is NULL, nor are there entity nodes to find if the 564 * search criteria are unspecified when entity is NULL. 565 */ 566 pldm_entity_node * 567 pldm_entity_association_tree_find(pldm_entity_association_tree *tree, 568 pldm_entity *entity); 569 570 /** @brief Find an entity in the entity association tree with locality specified, 571 * ie - remote entity or local entity 572 * 573 * @param[in] tree - pointer to entity association tree 574 * @param[in/out] entity - entity type and instance id set on input, container 575 * id set on output 576 * @param[in] is_remote - variable to denote whether we are finding a remote 577 * entity or a local entity 578 * 579 * @return pldm_entity_node* pointer to entity if found, NULL otherwise 580 */ 581 pldm_entity_node *pldm_entity_association_tree_find_with_locality( 582 pldm_entity_association_tree *tree, pldm_entity *entity, 583 bool is_remote); 584 585 /** @brief Create a copy of an existing entity association tree 586 * 587 * @pre org_tree must point to a valid object 588 * @pre new_tree must point to a valid object 589 * 590 * @param[in] org_tree - pointer to source tree 591 * @param[in/out] new_tree - pointer to destination tree 592 */ 593 void pldm_entity_association_tree_copy_root( 594 pldm_entity_association_tree *org_tree, 595 pldm_entity_association_tree *new_tree); 596 597 /** @brief Create a copy of an existing entity association tree 598 * 599 * @param[in] org_tree - pointer to source tree 600 * @param[in/out] new_tree - pointer to destination tree 601 * 602 * @return 0 if the entity association tree was copied, -EINVAL if the argument 603 * values are invalid, or -ENOMEM if memory required for the copy 604 * cannot be allocated. 605 */ 606 int pldm_entity_association_tree_copy_root_check( 607 pldm_entity_association_tree *org_tree, 608 pldm_entity_association_tree *new_tree); 609 610 /** @brief Destroy all the nodes of the entity association tree 611 * 612 * @param[in] tree - pointer to entity association tree 613 * 614 * There is no tree to destroy if tree is NULL. 615 */ 616 void pldm_entity_association_tree_destroy_root( 617 pldm_entity_association_tree *tree); 618 619 /** @brief Check whether the entity association tree is empty 620 * 621 * @pre tree must point to a valid object 622 * 623 * @param[in] tree - pointer to entity association tree 624 * @return bool, true if tree is empty 625 */ 626 bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree); 627 628 /** @brief Extract entities from entity association PDR 629 * 630 * @pre `*entities == NULL` and `*num_entities == 0` must hold at the time of invocation. 631 * 632 * @param[in] pdr - entity association PDR 633 * @param[in] pdr_len - size of entity association PDR in bytes 634 * @param[out] num_entities - number of entities found, including the container 635 * @param[out] entities - extracted entities, container is *entities[0]. Caller 636 * must free *entities 637 */ 638 void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len, 639 size_t *num_entities, 640 pldm_entity **entities); 641 642 /** @brief Remove a contained entity from an entity association PDR 643 * 644 * @param[in] repo - opaque pointer acting as a PDR repo handle 645 * @param[in] entity - the pldm entity to be deleted. Data inside the entity struct must be 646 * host-endianess format 647 * @param[in] is_remote - indicates which PDR to remove, local or remote 648 * @param[in-out] pdr_record_handle - record handle of the container entity which has to be removed. 649 * PLDM will use this record handle to updated the PDR repo so 650 * that entry corresponding to this entity is removed from PDR 651 * table. 652 * 653 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 654 * allocation fails, or -EOVERFLOW if given data is too large for memory allocated 655 */ 656 int pldm_entity_association_pdr_remove_contained_entity( 657 pldm_pdr *repo, pldm_entity *entity, bool is_remote, 658 uint32_t *pdr_record_handle); 659 660 /** @brief removes a PLDM PDR record if it matches given record set identifier 661 * @param[in] repo - opaque pointer acting as a PDR repo handle 662 * @param[in] fru_rsi - FRU record set identifier 663 * @param[in] is_remote - indicates which PDR to remove, local or remote 664 * @param[out] record_handle - record handle of the fru record to be removed 665 * 666 * @return 0 on success, -EINVAL if the arguments are invalid or -EOVERFLOW if value is too 667 * large for defined type 668 */ 669 int pldm_pdr_remove_fru_record_set_by_rsi(pldm_pdr *repo, uint16_t fru_rsi, 670 bool is_remote, 671 uint32_t *record_handle); 672 673 #ifdef __cplusplus 674 } 675 #endif 676 677 #endif /* PDR_H */ 678