blob: 4293d75f0e069741609cba1abb65454c913c24b4 [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#ifndef PDR_H
2#define PDR_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <stdbool.h>
9#include <stddef.h>
10#include <stdint.h>
11
12/** @struct pldm_pdr
13 * opaque structure that acts as a handle to a PDR repository
14 */
15typedef struct pldm_pdr pldm_pdr;
16
17/** @struct pldm_pdr_record
18 * opaque structure that acts as a handle to a PDR record
19 */
20typedef struct pldm_pdr_record pldm_pdr_record;
21
22/* ====================== */
23/* Common PDR access APIs */
24/* ====================== */
25
26/** @brief Make a new PDR repository
27 *
28 * @return opaque pointer that acts as a handle to the repository; NULL if no
29 * repository could be created
30 *
31 * @note Caller may make multiple repositories (for its own PDRs, as well as
32 * for PDRs received by other entities) and can associate the returned handle
33 * to a PLDM terminus id.
34 */
Andrew Jeffery319304f2023-04-05 13:53:18 +093035pldm_pdr *pldm_pdr_init(void);
Andrew Jeffery9c766792022-08-10 23:12:49 +093036
37/** @brief Destroy a PDR repository (and free up associated resources)
38 *
39 * @param[in/out] repo - pointer to opaque pointer acting as a PDR repo handle
40 */
41void pldm_pdr_destroy(pldm_pdr *repo);
42
43/** @brief Get number of records in a PDR repository
44 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +093045 * @pre repo must point to a valid object
46 *
Andrew Jeffery9c766792022-08-10 23:12:49 +093047 * @param[in] repo - opaque pointer acting as a PDR repo handle
48 *
49 * @return uint32_t - number of records
50 */
51uint32_t pldm_pdr_get_record_count(const pldm_pdr *repo);
52
53/** @brief Get size of a PDR repository, in bytes
54 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +093055 * @pre repo must point to a valid object
56 *
Andrew Jeffery9c766792022-08-10 23:12:49 +093057 * @param[in] repo - opaque pointer acting as a PDR repo handle
58 *
59 * @return uint32_t - size in bytes
60 */
61uint32_t pldm_pdr_get_repo_size(const pldm_pdr *repo);
62
Andrew Jeffery572a3952023-07-03 13:19:28 +093063/** @brief Add a PDR record to a PDR repository, or return an error
64 *
65 * @param[in/out] repo - opaque pointer acting as a PDR repo handle
66 * @param[in] data - pointer to a PDR record, pointing to a PDR definition as
67 * per DSP0248. This data is memcpy'd.
68 * @param[in] size - size of input PDR record in bytes
69 * @param[in] is_remote - if true, then the PDR is not from this terminus
70 * @param[in] terminus_handle - terminus handle of the input PDR record
71 * @param[in,out] record_handle - record handle of input PDR record. If this is set to 0 then a
72 * record handle is computed. The computed handle is assigned to both the PDR record and back into
73 * record_handle for the caller to consume.
74 *
75 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory
76 * allocation fails, or -EOVERFLOW if a record handle could not be allocated
77 */
78int pldm_pdr_add_check(pldm_pdr *repo, const uint8_t *data, uint32_t size,
79 bool is_remote, uint16_t terminus_handle,
80 uint32_t *record_handle);
81
Andrew Jeffery9c766792022-08-10 23:12:49 +093082/** @brief Get record handle of a PDR record
83 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +093084 * @pre repo must point to a valid object
85 * @pre record must point to a valid object
86 *
Andrew Jeffery9c766792022-08-10 23:12:49 +093087 * @param[in] repo - opaque pointer acting as a PDR repo handle
88 * @param[in] record - opaque pointer acting as a PDR record handle
89 *
90 * @return uint32_t - record handle assigned to PDR record; 0 if record is not
91 * found
92 */
93uint32_t pldm_pdr_get_record_handle(const pldm_pdr *repo,
94 const pldm_pdr_record *record);
95
96/** @brief Find PDR record by record handle
97 *
98 * @param[in] repo - opaque pointer acting as a PDR repo handle
99 * @param[in] record_handle - input record handle
100 * @param[in/out] data - will point to PDR record data (as per DSP0248) on
101 * return
102 * @param[out] size - *size will be size of PDR record
103 * @param[out] next_record_handle - *next_record_handle will be the record
104 * handle of record next to the returned PDR record
105 *
106 * @return opaque pointer acting as PDR record handle, will be NULL if record
107 * was not found
108 */
109const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo,
110 uint32_t record_handle,
111 uint8_t **data, uint32_t *size,
112 uint32_t *next_record_handle);
113
114/** @brief Get PDR record next to input PDR record
115 *
116 * @param[in] repo - opaque pointer acting as a PDR repo handle
117 * @param[in] curr_record - opaque pointer acting as a PDR record handle
118 * @param[in/out] data - will point to PDR record data (as per DSP0248) on
119 * return
120 * @param[out] size - *size will be size of PDR record
121 * @param[out] next_record_handle - *next_record_handle will be the record
122 * handle of record nect to the returned PDR record
123 *
124 * @return opaque pointer acting as PDR record handle, will be NULL if record
125 * was not found
126 */
127const pldm_pdr_record *
128pldm_pdr_get_next_record(const pldm_pdr *repo,
129 const pldm_pdr_record *curr_record, uint8_t **data,
130 uint32_t *size, uint32_t *next_record_handle);
131
132/** @brief Find (first) PDR record by PDR type
133 *
134 * @param[in] repo - opaque pointer acting as a PDR repo handle
135 * @param[in] pdr_type - PDR type number as per DSP0248
136 * @param[in] curr_record - opaque pointer acting as a PDR record handle; if
137 * not NULL, then search will begin from this record's next record
138 * @param[in/out] data - will point to PDR record data (as per DSP0248) on
139 * return, if input is not NULL
140 * @param[out] size - *size will be size of PDR record, if input is not NULL
141 *
142 * @return opaque pointer acting as PDR record handle, will be NULL if record
143 * was not found
144 */
145const pldm_pdr_record *
146pldm_pdr_find_record_by_type(const pldm_pdr *repo, uint8_t pdr_type,
147 const pldm_pdr_record *curr_record, uint8_t **data,
148 uint32_t *size);
149
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930150/** @brief Determine if a record is a remote record
151 *
152 * @pre record must point to a valid object
153 *
154 * @return true if the record is a remote record, false otherwise.
155 */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930156bool pldm_pdr_record_is_remote(const pldm_pdr_record *record);
157
158/** @brief Remove all PDR records that belong to a remote terminus
159 *
160 * @param[in] repo - opaque pointer acting as a PDR repo handle
Andrew Jeffery3e1d6592023-07-03 11:57:16 +0930161 *
162 * If repo is NULL then there are no PDRs that can be removed.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930163 */
164void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo);
165
166/** @brief Remove all remote PDR's that beling to a specific terminus
167 * handle
168 * @param[in] repo - opaque pointer acting as a PDR repo handle
169 * @param[in] terminus_handle - Terminus Handle of the remove PLDM terminus
Andrew Jeffery438dd492023-07-03 11:51:43 +0930170 *
171 * If repo is NULL there are no PDRs that can be removed.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930172 */
173void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo,
174 uint16_t terminus_handle);
175
176/** @brief Update the validity of TL PDR - the validity is decided based on
177 * whether the valid bit is set or not as per the spec DSP0248
178 *
179 * @param[in] repo - opaque pointer acting as a PDR repo handle
Andrew Jeffery6005f1c2023-04-05 20:02:52 +0930180 * @param[in] terminus_handle - PLDM terminus handle
Andrew Jeffery9c766792022-08-10 23:12:49 +0930181 * @param[in] tid - Terminus ID
Andrew Jeffery2a38ab52023-04-06 15:09:08 +0930182 * @param[in] tl_eid - MCTP endpoint EID
Andrew Jeffery9c766792022-08-10 23:12:49 +0930183 * @param[in] valid - validity bit of TLPDR
184 */
Andrew Jeffery6005f1c2023-04-05 20:02:52 +0930185/* NOLINTNEXTLINE(readability-identifier-naming) */
186void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminus_handle,
187 uint8_t tid, uint8_t tl_eid, bool valid);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930188
Pavithra Barithaya4d694342023-05-19 08:04:41 -0500189/** @brief Find the last record within the particular range
190 * of record handles
191 *
192 * @param[in] repo - pointer acting as a PDR repo handle
193 * @param[in] first - first record handle value of the records in the range
194 * @param[in] last - last record handle value of the records in the range
195 *
196 * @return pointer to the PDR record,will be NULL if record was not
197 * found
198 */
199pldm_pdr_record *pldm_pdr_find_last_in_range(const pldm_pdr *repo,
200 uint32_t first, uint32_t last);
201
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500202/** @brief find the container ID of the contained entity which is not in the
203 * particular range of record handles given
204 *
205 * @param[in] repo - opaque pointer acting as a PDR repo handle
206 * @param[in] entity_type - entity type
207 * @param[in] entity_instance - instance of the entity
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500208 * @param[in] child_index - index of the child entity whose container id needs to be found
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500209 * @param[in] range_exclude_start_handle - first record handle in the range of the remote endpoint
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500210 * which is ignored
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500211 * @param[in] range_exclude_end_handle - last record handle in the range of the remote endpoint
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500212 * which is ignored
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500213 * @param[out] container_id - container id of the contained entity
214 *
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500215 * @return container id of the PDR record found on success,-EINVAL when repo is NULL
216 * or -ENOKEY if the container id is not found.
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500217 */
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500218int pldm_pdr_find_child_container_id_index_range_exclude(
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500219 const pldm_pdr *repo, uint16_t entity_type, uint16_t entity_instance,
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500220 uint8_t child_index, uint32_t range_exclude_start_handle,
221 uint32_t range_exclude_end_handle, uint16_t *container_id);
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500222
Andrew Jeffery9c766792022-08-10 23:12:49 +0930223/* ======================= */
224/* FRU Record Set PDR APIs */
225/* ======================= */
226
Andrew Jefferyc821a702023-07-03 13:32:11 +0930227/** @brief Add a FRU record set PDR record to a PDR repository, or return an error
228 *
229 * @param[in/out] repo - opaque pointer acting as a PDR repo handle
230 * @param[in] terminus_handle - PLDM terminus handle of terminus owning the PDR
231 * record
232 * @param[in] fru_rsi - FRU record set identifier
233 * @param[in] entity_type - entity type of FRU
234 * @param[in] entity_instance_num - entity instance number of FRU
235 * @param[in] container_id - container id of FRU
236 * @param[in,out] bmc_record_handle - A pointer to the handle used to construct the next record. If
237 * the value is zero on input then a new handle is automatically allocated.
238 * Otherwise, the provided handle is used. If a new handle is automatically
239 * allocated then the object pointed to by bmc_record_handle will contain its value
240 * as output.
241 * @return 0 on success, -EINVAL if the arguments are invalid, or -ENOMEM if an internal allocation
242 * fails.
243 */
244int pldm_pdr_add_fru_record_set_check(pldm_pdr *repo, uint16_t terminus_handle,
245 uint16_t fru_rsi, uint16_t entity_type,
246 uint16_t entity_instance_num,
247 uint16_t container_id,
248 uint32_t *bmc_record_handle);
249
Andrew Jeffery9c766792022-08-10 23:12:49 +0930250/** @brief Find a FRU record set PDR by FRU record set identifier
251 *
252 * @param[in] repo - opaque pointer acting as a PDR repo handle
253 * @param[in] fru_rsi - FRU record set identifier
254 * @param[in] terminus_handle - *terminus_handle will be FRU terminus handle of
255 * found PDR, or 0 if not found
256 * @param[in] entity_type - *entity_type will be FRU entity type of found PDR,
257 * or 0 if not found
258 * @param[in] entity_instance_num - *entity_instance_num will be FRU entity
259 * instance number of found PDR, or 0 if not found
260 * @param[in] container_id - *cintainer_id will be FRU container id of found
261 * PDR, or 0 if not found
262 *
Andrew Jefferyaf7a4d82023-06-30 13:46:32 +0930263 * @return An opaque pointer to the PDR record on success, or NULL on failure
Andrew Jeffery9c766792022-08-10 23:12:49 +0930264 */
265const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930266 const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle,
267 uint16_t *entity_type, uint16_t *entity_instance_num,
268 uint16_t *container_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930269
270/* =========================== */
271/* Entity Association PDR APIs */
272/* =========================== */
273
274typedef struct pldm_entity {
275 uint16_t entity_type;
276 uint16_t entity_instance_num;
277 uint16_t entity_container_id;
278} __attribute__((packed)) pldm_entity;
279
280enum entity_association_containment_type {
281 PLDM_ENTITY_ASSOCIAION_PHYSICAL = 0x0,
282 PLDM_ENTITY_ASSOCIAION_LOGICAL = 0x1,
283};
284
285/** @struct pldm_entity_association_tree
286 * opaque structure that represents the entity association hierarchy
287 */
288typedef struct pldm_entity_association_tree pldm_entity_association_tree;
289
290/** @struct pldm_entity_node
291 * opaque structure that represents a node in the entity association hierarchy
292 */
293typedef struct pldm_entity_node pldm_entity_node;
294
295/** @brief Make a new entity association tree
296 *
297 * @return opaque pointer that acts as a handle to the tree; NULL if no
298 * tree could be created
299 */
Andrew Jeffery319304f2023-04-05 13:53:18 +0930300pldm_entity_association_tree *pldm_entity_association_tree_init(void);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930301
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500302/** @brief Add a local entity into the entity association tree
Andrew Jeffery9c766792022-08-10 23:12:49 +0930303 *
304 * @param[in/out] tree - opaque pointer acting as a handle to the tree
305 * @param[in/out] entity - pointer to the entity to be added. Input has the
306 * entity type. On output, instance number and the
307 * container id are populated.
308 * @param[in] entity_instance_number - entity instance number, we can use the
309 * entity instance number of the entity by
310 * default if its value is equal 0xFFFF.
311 * @param[in] parent - pointer to the node that should be the parent of input
312 * entity. If this is NULL, then the entity is the root
313 * @param[in] association_type - relation with the parent : logical or physical
314 *
315 * @return pldm_entity_node* - opaque pointer to added entity
316 */
317pldm_entity_node *pldm_entity_association_tree_add(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930318 pldm_entity_association_tree *tree, pldm_entity *entity,
319 uint16_t entity_instance_number, pldm_entity_node *parent,
320 uint8_t association_type);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930321
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500322/** @brief Add an entity into the entity association tree based on remote field
323 * set or unset.
324 *
325 * @param[in/out] tree - opaque pointer acting as a handle to the tree
326 * @param[in/out] entity - pointer to the entity to be added. Input has the
327 * entity type. On output, instance number and the
328 * container id are populated.
329 * @param[in] entity_instance_number - entity instance number, we can use the
330 * entity instance number of the entity by
331 * default if its value is equal 0xFFFF.
332 * @param[in] parent - pointer to the node that should be the parent of input
333 * entity. If this is NULL, then the entity is the root
334 * @param[in] association_type - relation with the parent : logical or physical
335 * @param[in] is_remote - used to denote whether we are adding a BMC entity to
336 * the tree or a host entity
337 * @param[in] is_update_contanier_id - Used to determine whether need to update
338 * contanier id.
339 * true: should be changed
340 * false: should not be changed
341 * @param[in] container_id - container id of the entity added.
342 *
343 * @return pldm_entity_node* - opaque pointer to added entity
344 */
345pldm_entity_node *pldm_entity_association_tree_add_entity(
346 pldm_entity_association_tree *tree, pldm_entity *entity,
347 uint16_t entity_instance_number, pldm_entity_node *parent,
348 uint8_t association_type, bool is_remote, bool is_update_container_id,
349 uint16_t container_id);
350
Andrew Jeffery9c766792022-08-10 23:12:49 +0930351/** @brief Visit and note each entity in the entity association tree
352 *
Andrew Jeffery8e9b0de2023-06-30 14:05:04 +0930353 * @pre `*entities == NULL` and `*size == 0` must hold at the time of invocation.
354 *
355 * Callers must inspect the values of `*entities` and `*size` post-invocation to determine if the
356 * invocation was a success or failure.
357 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930358 * @param[in] tree - opaque pointer acting as a handle to the tree
359 * @param[out] entities - pointer to list of pldm_entity's. To be free()'d by
360 * the caller
361 * @param[out] size - number of pldm_entity's
362 */
363void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree,
364 pldm_entity **entities, size_t *size);
365
366/** @brief Extract pldm entity by the pldm_entity_node
367 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930368 * @pre node must point to a valid object
369 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930370 * @param[in] node - opaque pointer to added entity
371 *
372 * @return pldm_entity - pldm entity
373 */
374pldm_entity pldm_entity_extract(pldm_entity_node *node);
375
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600376/** @brief Extract remote container id from the pldm_entity_node
377 *
Andrew Jeffery15b88182023-06-30 13:29:17 +0930378 * @pre entity must point to a valid object
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600379 *
Andrew Jeffery15b88182023-06-30 13:29:17 +0930380 * @param[in] entity - pointer to existing entity
381 *
382 * @return The remote container id
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600383 */
Andrew Jeffery15b88182023-06-30 13:29:17 +0930384uint16_t
385pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity);
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600386
Andrew Jeffery9c766792022-08-10 23:12:49 +0930387/** @brief Destroy entity association tree
388 *
389 * @param[in] tree - opaque pointer acting as a handle to the tree
390 */
391void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree);
392
393/** @brief Check if input enity node is a parent
394 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930395 * @pre node must point to a valid object
396 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930397 * @param[in] node - opaque pointer acting as a handle to an entity node
398 *
399 * @return bool true if node is a parent, false otherwise
400 */
401bool pldm_entity_is_node_parent(pldm_entity_node *node);
402
403/** @brief Get parent of entity
404 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930405 * @pre node must point to a valid object
406 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930407 * @param[in] node - opaque pointer acting as a handle to an entity node
408 *
409 * @return pldm_entity - pldm entity
410 */
411pldm_entity pldm_entity_get_parent(pldm_entity_node *node);
412
413/** @brief Check the current pldm entity is exist parent
414 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930415 * @pre node must point to a valid object
416 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930417 * @param[in] node - opaque pointer acting as a handle to an entity node
418 *
419 * @return bool true if exist parent, false otherwise
420 */
421bool pldm_entity_is_exist_parent(pldm_entity_node *node);
422
423/** @brief Convert entity association tree to PDR
424 *
Andrew Jefferyc7883482023-06-30 15:52:04 +0930425 * No conversion takes place if one or both of tree or repo are NULL.
426 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930427 * @param[in] tree - opaque pointer to entity association tree
428 * @param[in] repo - PDR repo where entity association records should be added
429 * @param[in] is_remote - if true, then the PDR is not from this terminus
430 * @param[in] terminus_handle - terminus handle of the terminus
431 */
432void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree,
433 pldm_pdr *repo, bool is_remote,
434 uint16_t terminus_handle);
Andrew Jefferycc394522023-07-03 12:49:31 +0930435
Andrew Jeffery65945992023-07-17 15:04:21 +0930436/** @brief Convert entity association tree to PDR, or return an error
437 *
438 * No conversion takes place if one or both of tree or repo are NULL.
439 *
440 * If an error is returned then the state and consistency of the PDR repository is undefined.
441 *
442 * @param[in] tree - opaque pointer to entity association tree
443 * @param[in] repo - PDR repo where entity association records should be added
444 * @param[in] is_remote - if true, then the PDR is not from this terminus
445 * @param[in] terminus_handle - terminus handle of the terminus
446 *
447 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory
448 * allocation fails, or -EOVERFLOW if a record handle could not be allocated
449 */
450int pldm_entity_association_pdr_add_check(pldm_entity_association_tree *tree,
451 pldm_pdr *repo, bool is_remote,
452 uint16_t terminus_handle);
453
Andrew Jefferycc394522023-07-03 12:49:31 +0930454/** @brief Add entity association pdr from node, or return an error
455 *
456 * @param[in] node - opaque pointer acting as a handle to an entity node
457 * @param[in] repo - PDR repo where entity association records should be added
458 * @param[in] is_remote - if true, then the PDR is not from this terminus
459 * @param[in] terminus_handle - terminus handle of the terminus
460 *
461 * @return 0 on success, -EINVAL if the provided arguments are invalid.
462 */
463int pldm_entity_association_pdr_add_from_node_check(
464 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities,
465 size_t num_entities, bool is_remote, uint16_t terminus_handle);
466
Pavithra Barithaya25ddbcc2023-05-19 08:28:59 -0500467/** @brief Add entity association pdr record based on record handle
468 * earlier the records where added in a sequential way alone, with
469 * this change the entity association PDR records gets the new record
470 * handle based on the input value given.
471 *
472 * @param[in] node - opaque pointer acting as a handle to an entity node
473 * @param[in] repo - PDR repo where entity association records should be added
474 * @param[in] is_remote - if true, then the PDR is not from this terminus
475 * @param[in] terminus_handle - terminus handle of the terminus
476 * @param[in] record_handle - record handle of the PDR
477 *
478 * @return 0 on succes, -EINVAL if the provided arguments are invalid.
479 */
480int pldm_entity_association_pdr_add_from_node_with_record_handle(
481 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities,
482 size_t num_entities, bool is_remote, uint16_t terminus_handle,
483 uint32_t record_handle);
484
Andrew Jeffery9c766792022-08-10 23:12:49 +0930485/** @brief Find entity reference in tree
486 *
487 * @param[in] tree - opaque pointer to entity association tree
488 * @param[in] entity - PLDM entity
489 * @param[in] node - node to the entity
490 */
491void pldm_find_entity_ref_in_tree(pldm_entity_association_tree *tree,
492 pldm_entity entity, pldm_entity_node **node);
493
494/** @brief Get number of children of entity
495 *
496 * @param[in] node - opaque pointer acting as a handle to an entity node
497 * @param[in] association_type - relation type filter : logical or physical
498 *
Andrew Jeffery6e8a2612023-06-30 15:36:48 +0930499 * @return uint8_t number of children. The returned value is zero if node is NULL or
500 * association_type is not one of PLDM_ENTITY_ASSOCIAION_PHYSICAL or
501 * PLDM_ENTITY_ASSOCIAION_LOGICAL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930502 */
503uint8_t pldm_entity_get_num_children(pldm_entity_node *node,
504 uint8_t association_type);
505
506/** @brief Verify that the current node is a child of the current parent
507 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930508 * @pre parent must point to a valid object
509 * @pre node must point to a valid object
510 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930511 * @param[in] parent - opaque pointer acting as a handle to an entity parent
512 * @param[in] node - pointer to the node of the pldm entity
Andrew Jeffery375d9fc2023-06-30 15:45:54 +0930513 *
514 * @return True if the node is a child of parent, false otherwise, including if one or both of
515 * parent or node are NULL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930516 */
517bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node);
518
519/** @brief Find an entity in the entity association tree
520 *
521 * @param[in] tree - pointer to entity association tree
522 * @param[in/out] entity - entity type and instance id set on input, container
523 * id set on output
Andrew Jeffery9c766792022-08-10 23:12:49 +0930524 * @return pldm_entity_node* pointer to entity if found, NULL otherwise
Andrew Jeffery94e364d2023-07-03 12:26:59 +0930525 *
526 * There are no entity nodes to search if tree is NULL, nor are there entity nodes to find if the
527 * search criteria are unspecified when entity is NULL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930528 */
529pldm_entity_node *
530pldm_entity_association_tree_find(pldm_entity_association_tree *tree,
531 pldm_entity *entity);
532
Sagar Srinivas302d9ff2023-08-01 02:11:30 -0500533/** @brief Find an entity in the entity association tree with locality specified,
534 * ie - remote entity or local entity
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500535 *
536 * @param[in] tree - pointer to entity association tree
537 * @param[in/out] entity - entity type and instance id set on input, container
538 * id set on output
Sagar Srinivas302d9ff2023-08-01 02:11:30 -0500539 * @param[in] is_remote - variable to denote whether we are finding a remote
540 * entity or a local entity
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500541 *
542 * @return pldm_entity_node* pointer to entity if found, NULL otherwise
543 */
Sagar Srinivas302d9ff2023-08-01 02:11:30 -0500544pldm_entity_node *pldm_entity_association_tree_find_with_locality(
545 pldm_entity_association_tree *tree, pldm_entity *entity,
546 bool is_remote);
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500547
Andrew Jeffery9c766792022-08-10 23:12:49 +0930548/** @brief Create a copy of an existing entity association tree
549 *
550 * @param[in] org_tree - pointer to source tree
551 * @param[in/out] new_tree - pointer to destination tree
552 */
553void pldm_entity_association_tree_copy_root(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930554 pldm_entity_association_tree *org_tree,
555 pldm_entity_association_tree *new_tree);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930556
557/** @brief Destroy all the nodes of the entity association tree
558 *
559 * @param[in] tree - pointer to entity association tree
Andrew Jeffery85d7a052023-07-03 12:29:24 +0930560 *
561 * There is no tree to destroy if tree is NULL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930562 */
563void pldm_entity_association_tree_destroy_root(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930564 pldm_entity_association_tree *tree);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930565
566/** @brief Check whether the entity association tree is empty
567 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930568 * @pre tree must point to a valid object
569 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930570 * @param[in] tree - pointer to entity association tree
571 * @return bool, true if tree is empty
572 */
573bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree);
574
575/** @brief Extract entities from entity association PDR
576 *
Andrew Jeffery3a5c46b2023-07-03 12:39:59 +0930577 * @pre `*entities == NULL` and `*num_entities == 0` must hold at the time of invocation.
578 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930579 * @param[in] pdr - entity association PDR
580 * @param[in] pdr_len - size of entity association PDR in bytes
581 * @param[out] num_entities - number of entities found, including the container
582 * @param[out] entities - extracted entities, container is *entities[0]. Caller
583 * must free *entities
584 */
585void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len,
586 size_t *num_entities,
587 pldm_entity **entities);
588
589#ifdef __cplusplus
590}
591#endif
592
593#endif /* PDR_H */