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