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_check(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 Find PDR record by record handle 98 * 99 * @param[in] repo - opaque pointer acting as a PDR repo handle 100 * @param[in] record_handle - input record handle 101 * @param[in/out] data - will point to PDR record data (as per DSP0248) on 102 * return 103 * @param[out] size - *size will be size of PDR record 104 * @param[out] next_record_handle - *next_record_handle will be the record 105 * handle of record next to the returned PDR record 106 * 107 * @return opaque pointer acting as PDR record handle, will be NULL if record 108 * was not found 109 */ 110 const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo, 111 uint32_t record_handle, 112 uint8_t **data, uint32_t *size, 113 uint32_t *next_record_handle); 114 115 /** @brief Get PDR record next to input PDR record 116 * 117 * @param[in] repo - opaque pointer acting as a PDR repo handle 118 * @param[in] curr_record - opaque pointer acting as a PDR record handle 119 * @param[in/out] data - will point to PDR record data (as per DSP0248) on 120 * return 121 * @param[out] size - *size will be size of PDR record 122 * @param[out] next_record_handle - *next_record_handle will be the record 123 * handle of record nect to the returned PDR record 124 * 125 * @return opaque pointer acting as PDR record handle, will be NULL if record 126 * was not found 127 */ 128 const pldm_pdr_record * 129 pldm_pdr_get_next_record(const pldm_pdr *repo, 130 const pldm_pdr_record *curr_record, uint8_t **data, 131 uint32_t *size, uint32_t *next_record_handle); 132 133 /** @brief Find (first) PDR record by PDR type 134 * 135 * @param[in] repo - opaque pointer acting as a PDR repo handle 136 * @param[in] pdr_type - PDR type number as per DSP0248 137 * @param[in] curr_record - opaque pointer acting as a PDR record handle; if 138 * not NULL, then search will begin from this record's next record 139 * @param[in/out] data - will point to PDR record data (as per DSP0248) on 140 * return, if input is not NULL 141 * @param[out] size - *size will be size of PDR record, if input is not NULL 142 * 143 * @return opaque pointer acting as PDR record handle, will be NULL if record 144 * was not found 145 */ 146 const pldm_pdr_record * 147 pldm_pdr_find_record_by_type(const pldm_pdr *repo, uint8_t pdr_type, 148 const pldm_pdr_record *curr_record, uint8_t **data, 149 uint32_t *size); 150 151 /** @brief Determine if a record is a remote record 152 * 153 * @pre record must point to a valid object 154 * 155 * @return true if the record is a remote record, false otherwise. 156 */ 157 bool pldm_pdr_record_is_remote(const pldm_pdr_record *record); 158 159 /** @brief Remove all PDR records that belong to a remote terminus 160 * 161 * @param[in] repo - opaque pointer acting as a PDR repo handle 162 * 163 * If repo is NULL then there are no PDRs that can be removed. 164 */ 165 void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo); 166 167 /** @brief Remove all remote PDR's that belong to a specific terminus 168 * handle 169 * @param[in] repo - opaque pointer acting as a PDR repo handle 170 * @param[in] terminus_handle - Terminus Handle of the remove PLDM terminus 171 * 172 * If repo is NULL there are no PDRs that can be removed. 173 */ 174 void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo, 175 uint16_t terminus_handle); 176 177 /** @brief Update the validity of TL PDR - the validity is decided based on 178 * whether the valid bit is set or not as per the spec DSP0248 179 * 180 * @param[in] repo - opaque pointer acting as a PDR repo handle 181 * @param[in] terminus_handle - PLDM terminus handle 182 * @param[in] tid - Terminus ID 183 * @param[in] tl_eid - MCTP endpoint EID 184 * @param[in] valid - validity bit of TLPDR 185 */ 186 /* NOLINTNEXTLINE(readability-identifier-naming) */ 187 void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminus_handle, 188 uint8_t tid, uint8_t tl_eid, bool valid); 189 190 /** @brief Find the last record within the particular range 191 * of record handles 192 * 193 * @param[in] repo - pointer acting as a PDR repo handle 194 * @param[in] first - first record handle value of the records in the range 195 * @param[in] last - last record handle value of the records in the range 196 * 197 * @return pointer to the PDR record,will be NULL if record was not 198 * found 199 */ 200 pldm_pdr_record *pldm_pdr_find_last_in_range(const pldm_pdr *repo, 201 uint32_t first, uint32_t last); 202 203 /** @brief find the container ID of the contained entity which is not in the 204 * particular range of record handles given 205 * 206 * @param[in] repo - opaque pointer acting as a PDR repo handle 207 * @param[in] entity_type - entity type 208 * @param[in] entity_instance - instance of the entity 209 * @param[in] child_index - index of the child entity whose container id needs to be found 210 * @param[in] range_exclude_start_handle - first record handle in the range of the remote endpoint 211 * which is ignored 212 * @param[in] range_exclude_end_handle - last record handle in the range of the remote endpoint 213 * which is ignored 214 * @param[out] container_id - container id of the contained entity 215 * 216 * @return container id of the PDR record found on success,-EINVAL when repo is NULL 217 * or -ENOKEY if the container id is not found. 218 */ 219 int pldm_pdr_find_child_container_id_index_range_exclude( 220 const pldm_pdr *repo, uint16_t entity_type, uint16_t entity_instance, 221 uint8_t child_index, uint32_t range_exclude_start_handle, 222 uint32_t range_exclude_end_handle, uint16_t *container_id); 223 224 /* ======================= */ 225 /* FRU Record Set PDR APIs */ 226 /* ======================= */ 227 228 /** @brief Add a FRU record set PDR record to a PDR repository, or return an error 229 * 230 * @param[in/out] repo - opaque pointer acting as a PDR repo handle 231 * @param[in] terminus_handle - PLDM terminus handle of terminus owning the PDR 232 * record 233 * @param[in] fru_rsi - FRU record set identifier 234 * @param[in] entity_type - entity type of FRU 235 * @param[in] entity_instance_num - entity instance number of FRU 236 * @param[in] container_id - container id of FRU 237 * @param[in,out] bmc_record_handle - A pointer to the handle used to construct the next record. If 238 * the value is zero on input then a new handle is automatically allocated. 239 * Otherwise, the provided handle is used. If a new handle is automatically 240 * allocated then the object pointed to by bmc_record_handle will contain its value 241 * as output. 242 * @return 0 on success, -EINVAL if the arguments are invalid, or -ENOMEM if an internal allocation 243 * fails. 244 */ 245 int pldm_pdr_add_fru_record_set_check(pldm_pdr *repo, uint16_t terminus_handle, 246 uint16_t fru_rsi, uint16_t entity_type, 247 uint16_t entity_instance_num, 248 uint16_t container_id, 249 uint32_t *bmc_record_handle); 250 251 /** @brief Find a FRU record set PDR by FRU record set identifier 252 * 253 * @param[in] repo - opaque pointer acting as a PDR repo handle 254 * @param[in] fru_rsi - FRU record set identifier 255 * @param[in] terminus_handle - *terminus_handle will be FRU terminus handle of 256 * found PDR, or 0 if not found 257 * @param[in] entity_type - *entity_type will be FRU entity type of found PDR, 258 * or 0 if not found 259 * @param[in] entity_instance_num - *entity_instance_num will be FRU entity 260 * instance number of found PDR, or 0 if not found 261 * @param[in] container_id - *cintainer_id will be FRU container id of found 262 * PDR, or 0 if not found 263 * 264 * @return An opaque pointer to the PDR record on success, or NULL on failure 265 */ 266 const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( 267 const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle, 268 uint16_t *entity_type, uint16_t *entity_instance_num, 269 uint16_t *container_id); 270 271 /* =========================== */ 272 /* Entity Association PDR APIs */ 273 /* =========================== */ 274 275 typedef struct pldm_entity { 276 uint16_t entity_type; 277 uint16_t entity_instance_num; 278 uint16_t entity_container_id; 279 } __attribute__((packed)) pldm_entity; 280 281 enum entity_association_containment_type { 282 PLDM_ENTITY_ASSOCIAION_PHYSICAL = 0x0, 283 PLDM_ENTITY_ASSOCIAION_LOGICAL = 0x1, 284 }; 285 286 /** @struct pldm_entity_association_tree 287 * opaque structure that represents the entity association hierarchy 288 */ 289 typedef struct pldm_entity_association_tree pldm_entity_association_tree; 290 291 /** @struct pldm_entity_node 292 * opaque structure that represents a node in the entity association hierarchy 293 */ 294 typedef struct pldm_entity_node pldm_entity_node; 295 296 /** @brief Make a new entity association tree 297 * 298 * @return opaque pointer that acts as a handle to the tree; NULL if no 299 * tree could be created 300 */ 301 pldm_entity_association_tree *pldm_entity_association_tree_init(void); 302 303 /** @brief Add a local entity into the entity association tree 304 * 305 * @param[in/out] tree - opaque pointer acting as a handle to the tree 306 * @param[in/out] entity - pointer to the entity to be added. Input has the 307 * entity type. On output, instance number and the 308 * container id are populated. 309 * @param[in] entity_instance_number - entity instance number, we can use the 310 * entity instance number of the entity by 311 * default if its value is equal 0xffff. 312 * @param[in] parent - pointer to the node that should be the parent of input 313 * entity. If this is NULL, then the entity is the root 314 * @param[in] association_type - relation with the parent : logical or physical 315 * 316 * @return pldm_entity_node* - opaque pointer to added entity 317 */ 318 pldm_entity_node *pldm_entity_association_tree_add( 319 pldm_entity_association_tree *tree, pldm_entity *entity, 320 uint16_t entity_instance_number, pldm_entity_node *parent, 321 uint8_t association_type); 322 323 /** @brief Add an entity into the entity association tree based on remote field 324 * set or unset. 325 * 326 * @param[in/out] tree - opaque pointer acting as a handle to the tree 327 * @param[in/out] entity - pointer to the entity to be added. Input has the 328 * entity type. On output, instance number and the 329 * container id are populated. 330 * @param[in] entity_instance_number - entity instance number, we can use the 331 * entity instance number of the entity by 332 * default if its value is equal 0xffff. 333 * @param[in] parent - pointer to the node that should be the parent of input 334 * entity. If this is NULL, then the entity is the root 335 * @param[in] association_type - relation with the parent : logical or physical 336 * @param[in] is_remote - used to denote whether we are adding a BMC entity to 337 * the tree or a host entity 338 * @param[in] is_update_contanier_id - Used to determine whether need to update 339 * contanier id. 340 * true: should be changed 341 * false: should not be changed 342 * @param[in] container_id - container id of the entity added. 343 * 344 * @return pldm_entity_node* - opaque pointer to added entity 345 */ 346 pldm_entity_node *pldm_entity_association_tree_add_entity( 347 pldm_entity_association_tree *tree, pldm_entity *entity, 348 uint16_t entity_instance_number, pldm_entity_node *parent, 349 uint8_t association_type, bool is_remote, bool is_update_container_id, 350 uint16_t container_id); 351 352 /** @brief Visit and note each entity in the entity association tree 353 * 354 * @pre `*entities == NULL` and `*size == 0` must hold at the time of invocation. 355 * 356 * Callers must inspect the values of `*entities` and `*size` post-invocation to determine if the 357 * invocation was a success or failure. 358 * 359 * @param[in] tree - opaque pointer acting as a handle to the tree 360 * @param[out] entities - pointer to list of pldm_entity's. To be free()'d by 361 * the caller 362 * @param[out] size - number of pldm_entity's 363 */ 364 void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree, 365 pldm_entity **entities, size_t *size); 366 367 /** @brief Extract pldm entity by the pldm_entity_node 368 * 369 * @pre node must point to a valid object 370 * 371 * @param[in] node - opaque pointer to added entity 372 * 373 * @return pldm_entity - pldm entity 374 */ 375 pldm_entity pldm_entity_extract(pldm_entity_node *node); 376 377 /** @brief Extract remote container id from the pldm_entity_node 378 * 379 * @pre entity must point to a valid object 380 * 381 * @param[in] entity - pointer to existing entity 382 * 383 * @return The remote container id 384 */ 385 uint16_t 386 pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity); 387 388 /** @brief Destroy entity association tree 389 * 390 * @param[in] tree - opaque pointer acting as a handle to the tree 391 */ 392 void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree); 393 394 /** @brief Check if input entity node is a parent 395 * 396 * @pre node must point to a valid object 397 * 398 * @param[in] node - opaque pointer acting as a handle to an entity node 399 * 400 * @return bool true if node is a parent, false otherwise 401 */ 402 bool pldm_entity_is_node_parent(pldm_entity_node *node); 403 404 /** @brief Get parent of entity 405 * 406 * @pre node must point to a valid object 407 * 408 * @param[in] node - opaque pointer acting as a handle to an entity node 409 * 410 * @return pldm_entity - pldm entity 411 */ 412 pldm_entity pldm_entity_get_parent(pldm_entity_node *node); 413 414 /** @brief Check the current pldm entity is exist parent 415 * 416 * @pre node must point to a valid object 417 * 418 * @param[in] node - opaque pointer acting as a handle to an entity node 419 * 420 * @return bool true if exist parent, false otherwise 421 */ 422 bool pldm_entity_is_exist_parent(pldm_entity_node *node); 423 424 /** @brief Convert entity association tree to PDR 425 * 426 * No conversion takes place if one or both of tree or repo are NULL. 427 * 428 * @param[in] tree - opaque pointer to entity association tree 429 * @param[in] repo - PDR repo where entity association records should be added 430 * @param[in] is_remote - if true, then the PDR is not from this terminus 431 * @param[in] terminus_handle - terminus handle of the terminus 432 */ 433 void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree, 434 pldm_pdr *repo, bool is_remote, 435 uint16_t terminus_handle); 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_check(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_check( 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 Destroy all the nodes of the entity association tree 598 * 599 * @param[in] tree - pointer to entity association tree 600 * 601 * There is no tree to destroy if tree is NULL. 602 */ 603 void pldm_entity_association_tree_destroy_root( 604 pldm_entity_association_tree *tree); 605 606 /** @brief Check whether the entity association tree is empty 607 * 608 * @pre tree must point to a valid object 609 * 610 * @param[in] tree - pointer to entity association tree 611 * @return bool, true if tree is empty 612 */ 613 bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree); 614 615 /** @brief Extract entities from entity association PDR 616 * 617 * @pre `*entities == NULL` and `*num_entities == 0` must hold at the time of invocation. 618 * 619 * @param[in] pdr - entity association PDR 620 * @param[in] pdr_len - size of entity association PDR in bytes 621 * @param[out] num_entities - number of entities found, including the container 622 * @param[out] entities - extracted entities, container is *entities[0]. Caller 623 * must free *entities 624 */ 625 void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len, 626 size_t *num_entities, 627 pldm_entity **entities); 628 629 #ifdef __cplusplus 630 } 631 #endif 632 633 #endif /* PDR_H */ 634