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 /** @brief Delete record using its record handle 238 * 239 * @param[in] repo - opaque pointer acting as a PDR repo handle 240 * @param[in] record_handle - record handle of input PDR record 241 * @param[in] is_remote - if true, then the PDR is not from this terminus 242 * 243 * @return 0 if deleted successful else returns -EINVAL when repo is NULL 244 * or -ENOENT if the record handle is not found in the repo. 245 */ 246 int pldm_pdr_delete_by_record_handle(pldm_pdr *repo, uint32_t record_handle, 247 bool is_remote); 248 249 /* ======================= */ 250 /* FRU Record Set PDR APIs */ 251 /* ======================= */ 252 253 /** @brief Add a FRU record set PDR record to a PDR repository, or return an error 254 * 255 * @param[in/out] repo - opaque pointer acting as a PDR repo handle 256 * @param[in] terminus_handle - PLDM terminus handle of terminus owning the PDR 257 * record 258 * @param[in] fru_rsi - FRU record set identifier 259 * @param[in] entity_type - entity type of FRU 260 * @param[in] entity_instance_num - entity instance number of FRU 261 * @param[in] container_id - container id of FRU 262 * @param[in,out] bmc_record_handle - A pointer to the handle used to construct the next record. If 263 * the value is zero on input then a new handle is automatically allocated. 264 * Otherwise, the provided handle is used. If a new handle is automatically 265 * allocated then the object pointed to by bmc_record_handle will contain its value 266 * as output. 267 * @return 0 on success, -EINVAL if the arguments are invalid, or -ENOMEM if an internal allocation 268 * fails. 269 */ 270 int pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle, 271 uint16_t fru_rsi, uint16_t entity_type, 272 uint16_t entity_instance_num, 273 uint16_t container_id, 274 uint32_t *bmc_record_handle); 275 276 /** @brief Find a FRU record set PDR by FRU record set identifier 277 * 278 * @param[in] repo - opaque pointer acting as a PDR repo handle 279 * @param[in] fru_rsi - FRU record set identifier 280 * @param[in] terminus_handle - *terminus_handle will be FRU terminus handle of 281 * found PDR, or 0 if not found 282 * @param[in] entity_type - *entity_type will be FRU entity type of found PDR, 283 * or 0 if not found 284 * @param[in] entity_instance_num - *entity_instance_num will be FRU entity 285 * instance number of found PDR, or 0 if not found 286 * @param[in] container_id - *cintainer_id will be FRU container id of found 287 * PDR, or 0 if not found 288 * 289 * @return An opaque pointer to the PDR record on success, or NULL on failure 290 */ 291 const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( 292 const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle, 293 uint16_t *entity_type, uint16_t *entity_instance_num, 294 uint16_t *container_id); 295 296 /* =========================== */ 297 /* Entity Association PDR APIs */ 298 /* =========================== */ 299 300 typedef struct pldm_entity { 301 uint16_t entity_type; 302 uint16_t entity_instance_num; 303 uint16_t entity_container_id; 304 } __attribute__((packed)) pldm_entity; 305 306 enum entity_association_containment_type { 307 PLDM_ENTITY_ASSOCIAION_PHYSICAL = 0x0, 308 PLDM_ENTITY_ASSOCIAION_LOGICAL = 0x1, 309 }; 310 311 /** @struct pldm_entity_association_tree 312 * opaque structure that represents the entity association hierarchy 313 */ 314 typedef struct pldm_entity_association_tree pldm_entity_association_tree; 315 316 /** @struct pldm_entity_node 317 * opaque structure that represents a node in the entity association hierarchy 318 */ 319 typedef struct pldm_entity_node pldm_entity_node; 320 321 /** @brief Make a new entity association tree 322 * 323 * @return opaque pointer that acts as a handle to the tree; NULL if no 324 * tree could be created 325 */ 326 pldm_entity_association_tree *pldm_entity_association_tree_init(void); 327 328 /** @brief Add a local entity into the entity association tree 329 * 330 * @param[in/out] tree - opaque pointer acting as a handle to the tree 331 * @param[in/out] entity - pointer to the entity to be added. Input has the 332 * entity type. On output, instance number and the 333 * container id are populated. 334 * @param[in] entity_instance_number - entity instance number, we can use the 335 * entity instance number of the entity by 336 * default if its value is equal 0xffff. 337 * @param[in] parent - pointer to the node that should be the parent of input 338 * entity. If this is NULL, then the entity is the root 339 * @param[in] association_type - relation with the parent : logical or physical 340 * 341 * @return pldm_entity_node* - opaque pointer to added entity 342 */ 343 pldm_entity_node *pldm_entity_association_tree_add( 344 pldm_entity_association_tree *tree, pldm_entity *entity, 345 uint16_t entity_instance_number, pldm_entity_node *parent, 346 uint8_t association_type); 347 348 /** @brief Add an entity into the entity association tree based on remote field 349 * set or unset. 350 * 351 * @param[in/out] tree - opaque pointer acting as a handle to the tree 352 * @param[in/out] entity - pointer to the entity to be added. Input has the 353 * entity type. On output, instance number and the 354 * container id are populated. 355 * @param[in] entity_instance_number - entity instance number, we can use the 356 * entity instance number of the entity by 357 * default if its value is equal 0xffff. 358 * @param[in] parent - pointer to the node that should be the parent of input 359 * entity. If this is NULL, then the entity is the root 360 * @param[in] association_type - relation with the parent : logical or physical 361 * @param[in] is_remote - used to denote whether we are adding a BMC entity to 362 * the tree or a host entity 363 * @param[in] is_update_contanier_id - Used to determine whether need to update 364 * contanier id. 365 * true: should be changed 366 * false: should not be changed 367 * @param[in] container_id - container id of the entity added. 368 * 369 * @return pldm_entity_node* - opaque pointer to added entity 370 */ 371 pldm_entity_node *pldm_entity_association_tree_add_entity( 372 pldm_entity_association_tree *tree, pldm_entity *entity, 373 uint16_t entity_instance_number, pldm_entity_node *parent, 374 uint8_t association_type, bool is_remote, bool is_update_container_id, 375 uint16_t container_id); 376 377 /** @brief Visit and note each entity in the entity association tree 378 * 379 * @pre `*entities == NULL` and `*size == 0` must hold at the time of invocation. 380 * 381 * Callers must inspect the values of `*entities` and `*size` post-invocation to determine if the 382 * invocation was a success or failure. 383 * 384 * @param[in] tree - opaque pointer acting as a handle to the tree 385 * @param[out] entities - pointer to list of pldm_entity's. To be free()'d by 386 * the caller 387 * @param[out] size - number of pldm_entity's 388 */ 389 void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree, 390 pldm_entity **entities, size_t *size); 391 392 /** @brief Extract pldm entity by the pldm_entity_node 393 * 394 * @pre node must point to a valid object 395 * 396 * @param[in] node - opaque pointer to added entity 397 * 398 * @return pldm_entity - pldm entity 399 */ 400 pldm_entity pldm_entity_extract(pldm_entity_node *node); 401 402 /** @brief Extract remote container id from the pldm_entity_node 403 * 404 * @pre entity must point to a valid object 405 * 406 * @param[in] entity - pointer to existing entity 407 * 408 * @return The remote container id 409 */ 410 uint16_t 411 pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity); 412 413 /** @brief Destroy entity association tree 414 * 415 * @param[in] tree - opaque pointer acting as a handle to the tree 416 */ 417 void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree); 418 419 /** @brief Check if input entity node is a parent 420 * 421 * @pre node must point to a valid object 422 * 423 * @param[in] node - opaque pointer acting as a handle to an entity node 424 * 425 * @return bool true if node is a parent, false otherwise 426 */ 427 bool pldm_entity_is_node_parent(pldm_entity_node *node); 428 429 /** @brief Get parent of entity 430 * 431 * @pre node must point to a valid object 432 * 433 * @param[in] node - opaque pointer acting as a handle to an entity node 434 * 435 * @return pldm_entity - pldm entity 436 */ 437 pldm_entity pldm_entity_get_parent(pldm_entity_node *node); 438 439 /** @brief Check the current pldm entity is exist parent 440 * 441 * @pre node must point to a valid object 442 * 443 * @param[in] node - opaque pointer acting as a handle to an entity node 444 * 445 * @return bool true if exist parent, false otherwise 446 */ 447 bool pldm_entity_is_exist_parent(pldm_entity_node *node); 448 449 /** @brief Convert entity association tree to PDR, or return an error 450 * 451 * No conversion takes place if one or both of tree or repo are NULL. 452 * 453 * If an error is returned then the state and consistency of the PDR repository is undefined. 454 * 455 * @param[in] tree - opaque pointer to entity association tree 456 * @param[in] repo - PDR repo where entity association records should be added 457 * @param[in] is_remote - if true, then the PDR is not from this terminus 458 * @param[in] terminus_handle - terminus handle of the terminus 459 * 460 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 461 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 462 */ 463 int pldm_entity_association_pdr_add(pldm_entity_association_tree *tree, 464 pldm_pdr *repo, bool is_remote, 465 uint16_t terminus_handle); 466 467 /** @brief Add a contained entity as a remote PDR to an existing entity association PDR. 468 * 469 * Remote PDRs are PDRs added as a child to an entity in the entity association tree and 470 * not to the tree directly. This means remote PDRs have a parent PDR in the entity 471 * association tree to which they are linked. 472 * 473 * @param[in] repo - opaque pointer to pldm PDR repo 474 * @param[in] entity - the contained entity to be added 475 * @param[in] pdr_record_handle - record handle of the container entity to which the remote 476 * PDR is to be added as a child 477 * 478 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 479 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 480 */ 481 int pldm_entity_association_pdr_add_contained_entity_to_remote_pdr( 482 pldm_pdr *repo, pldm_entity *entity, uint32_t pdr_record_handle); 483 484 /** @brief Creates a new entity association PDR with contained entity & its parent. 485 * 486 * @param[in] repo - opaque pointer to pldm PDR repo 487 * @param[in] pdr_record_handle - record handle of the PDR after which the new container 488 * entity has to be added 489 * @param[in] parent - the container entity 490 * @param[in] entity - the contained entity to be added 491 * @param[in-out] entity_record_handle - record handle of a container entity added to the 492 * entity association PDR 493 * 494 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 495 * allocation fails, or -EOVERFLOW if a record handle could not be allocated 496 */ 497 int pldm_entity_association_pdr_create_new(pldm_pdr *repo, 498 uint32_t pdr_record_handle, 499 pldm_entity *parent, 500 pldm_entity *entity, 501 uint32_t *entity_record_handle); 502 503 /** @brief Add entity association pdr from node, or return an error 504 * 505 * @param[in] node - opaque pointer acting as a handle to an entity node 506 * @param[in] repo - PDR repo where entity association records should be added 507 * @param[in] is_remote - if true, then the PDR is not from this terminus 508 * @param[in] terminus_handle - terminus handle of the terminus 509 * 510 * @return 0 on success, -EINVAL if the provided arguments are invalid. 511 */ 512 int pldm_entity_association_pdr_add_from_node( 513 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities, 514 size_t num_entities, bool is_remote, uint16_t terminus_handle); 515 516 /** @brief Add entity association pdr record based on record handle 517 * earlier the records where added in a sequential way alone, with 518 * this change the entity association PDR records gets the new record 519 * handle based on the input value given. 520 * 521 * @param[in] node - opaque pointer acting as a handle to an entity node 522 * @param[in] repo - PDR repo where entity association records should be added 523 * @param[in] is_remote - if true, then the PDR is not from this terminus 524 * @param[in] terminus_handle - terminus handle of the terminus 525 * @param[in] record_handle - record handle of the PDR 526 * 527 * @return 0 on success, -EINVAL if the provided arguments are invalid. 528 */ 529 int pldm_entity_association_pdr_add_from_node_with_record_handle( 530 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities, 531 size_t num_entities, bool is_remote, uint16_t terminus_handle, 532 uint32_t record_handle); 533 534 /** @brief Find entity reference in tree 535 * 536 * @param[in] tree - opaque pointer to entity association tree 537 * @param[in] entity - PLDM entity 538 * @param[in] node - node to the entity 539 */ 540 void pldm_find_entity_ref_in_tree(pldm_entity_association_tree *tree, 541 pldm_entity entity, pldm_entity_node **node); 542 543 /** @brief Get number of children of entity 544 * 545 * @param[in] node - opaque pointer acting as a handle to an entity node 546 * @param[in] association_type - relation type filter : logical or physical 547 * 548 * @return uint8_t number of children. The returned value is zero if node is NULL or 549 * association_type is not one of PLDM_ENTITY_ASSOCIAION_PHYSICAL or 550 * PLDM_ENTITY_ASSOCIAION_LOGICAL. 551 */ 552 uint8_t pldm_entity_get_num_children(pldm_entity_node *node, 553 uint8_t association_type); 554 555 /** @brief Verify that the current node is a child of the current parent 556 * 557 * @pre parent must point to a valid object 558 * @pre node must point to a valid object 559 * 560 * @param[in] parent - opaque pointer acting as a handle to an entity parent 561 * @param[in] node - pointer to the node of the pldm entity 562 * 563 * @return True if the node is a child of parent, false otherwise, including if one or both of 564 * parent or node are NULL. 565 */ 566 bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node); 567 568 /** @brief Find an entity in the entity association tree 569 * 570 * @param[in] tree - pointer to entity association tree 571 * @param[in/out] entity - entity type and instance id set on input, container 572 * id set on output 573 * @return pldm_entity_node* pointer to entity if found, NULL otherwise 574 * 575 * There are no entity nodes to search if tree is NULL, nor are there entity nodes to find if the 576 * search criteria are unspecified when entity is NULL. 577 */ 578 pldm_entity_node * 579 pldm_entity_association_tree_find(pldm_entity_association_tree *tree, 580 pldm_entity *entity); 581 582 /** @brief Find an entity in the entity association tree with locality specified, 583 * ie - remote entity or local entity 584 * 585 * @param[in] tree - pointer to entity association tree 586 * @param[in/out] entity - entity type and instance id set on input, container 587 * id set on output 588 * @param[in] is_remote - variable to denote whether we are finding a remote 589 * entity or a local entity 590 * 591 * @return pldm_entity_node* pointer to entity if found, NULL otherwise 592 */ 593 pldm_entity_node *pldm_entity_association_tree_find_with_locality( 594 pldm_entity_association_tree *tree, pldm_entity *entity, 595 bool is_remote); 596 597 /** @brief Create a copy of an existing entity association tree 598 * 599 * @pre org_tree must point to a valid object 600 * @pre new_tree must point to a valid object 601 * 602 * @param[in] org_tree - pointer to source tree 603 * @param[in/out] new_tree - pointer to destination tree 604 */ 605 void pldm_entity_association_tree_copy_root( 606 pldm_entity_association_tree *org_tree, 607 pldm_entity_association_tree *new_tree); 608 609 /** @brief Create a copy of an existing entity association tree 610 * 611 * @param[in] org_tree - pointer to source tree 612 * @param[in/out] new_tree - pointer to destination tree 613 * 614 * @return 0 if the entity association tree was copied, -EINVAL if the argument 615 * values are invalid, or -ENOMEM if memory required for the copy 616 * cannot be allocated. 617 */ 618 int pldm_entity_association_tree_copy_root_check( 619 pldm_entity_association_tree *org_tree, 620 pldm_entity_association_tree *new_tree); 621 622 /** @brief Destroy all the nodes of the entity association tree 623 * 624 * @param[in] tree - pointer to entity association tree 625 * 626 * There is no tree to destroy if tree is NULL. 627 */ 628 void pldm_entity_association_tree_destroy_root( 629 pldm_entity_association_tree *tree); 630 631 /** @brief Check whether the entity association tree is empty 632 * 633 * @pre tree must point to a valid object 634 * 635 * @param[in] tree - pointer to entity association tree 636 * @return bool, true if tree is empty 637 */ 638 bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree); 639 640 /** @brief Extract entities from entity association PDR 641 * 642 * @pre `*entities == NULL` and `*num_entities == 0` must hold at the time of invocation. 643 * 644 * @param[in] pdr - entity association PDR 645 * @param[in] pdr_len - size of entity association PDR in bytes 646 * @param[out] num_entities - number of entities found, including the container 647 * @param[out] entities - extracted entities, container is *entities[0]. Caller 648 * must free *entities 649 */ 650 void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len, 651 size_t *num_entities, 652 pldm_entity **entities); 653 654 /** @brief Remove a contained entity from an entity association PDR 655 * 656 * @param[in] repo - opaque pointer acting as a PDR repo handle 657 * @param[in] entity - the pldm entity to be deleted. Data inside the entity struct must be 658 * host-endianess format 659 * @param[in] is_remote - indicates which PDR to remove, local or remote 660 * @param[in-out] pdr_record_handle - record handle of the container entity which has to be removed. 661 * PLDM will use this record handle to updated the PDR repo so 662 * that entry corresponding to this entity is removed from PDR 663 * table. 664 * 665 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory 666 * allocation fails, or -EOVERFLOW if given data is too large for memory allocated 667 */ 668 int pldm_entity_association_pdr_remove_contained_entity( 669 pldm_pdr *repo, pldm_entity *entity, bool is_remote, 670 uint32_t *pdr_record_handle); 671 672 /** @brief removes a PLDM PDR record if it matches given record set identifier 673 * @param[in] repo - opaque pointer acting as a PDR repo handle 674 * @param[in] fru_rsi - FRU record set identifier 675 * @param[in] is_remote - indicates which PDR to remove, local or remote 676 * @param[out] record_handle - record handle of the fru record to be removed 677 * 678 * @return 0 on success, -EINVAL if the arguments are invalid or -EOVERFLOW if value is too 679 * large for defined type 680 */ 681 int pldm_pdr_remove_fru_record_set_by_rsi(pldm_pdr *repo, uint16_t fru_rsi, 682 bool is_remote, 683 uint32_t *record_handle); 684 685 #ifdef __cplusplus 686 } 687 #endif 688 689 #endif /* PDR_H */ 690