blob: 621974aa7e2d6b549fcb0061df6f0ed509bdb2c8 [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
63/** @brief Add a PDR record to a PDR repository
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] record_handle - record handle of input PDR record; if this is set
70 * to 0, then a record handle is computed and assigned to this PDR record
71 * @param[in] is_remote - if true, then the PDR is not from this terminus
72 * @param[in] terminus_handle - terminus handle of the input PDR record
73 *
74 * @return uint32_t - record handle assigned to PDR record
75 */
76uint32_t pldm_pdr_add(pldm_pdr *repo, const uint8_t *data, uint32_t size,
77 uint32_t record_handle, bool is_remote,
78 uint16_t terminus_handle);
79
Andrew Jeffery572a3952023-07-03 13:19:28 +093080/** @brief Add a PDR record to a PDR repository, or return an error
81 *
82 * @param[in/out] repo - opaque pointer acting as a PDR repo handle
83 * @param[in] data - pointer to a PDR record, pointing to a PDR definition as
84 * per DSP0248. This data is memcpy'd.
85 * @param[in] size - size of input PDR record in bytes
86 * @param[in] is_remote - if true, then the PDR is not from this terminus
87 * @param[in] terminus_handle - terminus handle of the input PDR record
88 * @param[in,out] record_handle - record handle of input PDR record. If this is set to 0 then a
89 * record handle is computed. The computed handle is assigned to both the PDR record and back into
90 * record_handle for the caller to consume.
91 *
92 * @return 0 on success, -EINVAL if the arguments are invalid, -ENOMEM if an internal memory
93 * allocation fails, or -EOVERFLOW if a record handle could not be allocated
94 */
95int pldm_pdr_add_check(pldm_pdr *repo, const uint8_t *data, uint32_t size,
96 bool is_remote, uint16_t terminus_handle,
97 uint32_t *record_handle);
98
Andrew Jeffery9c766792022-08-10 23:12:49 +093099/** @brief Get record handle of a PDR record
100 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930101 * @pre repo must point to a valid object
102 * @pre record must point to a valid object
103 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930104 * @param[in] repo - opaque pointer acting as a PDR repo handle
105 * @param[in] record - opaque pointer acting as a PDR record handle
106 *
107 * @return uint32_t - record handle assigned to PDR record; 0 if record is not
108 * found
109 */
110uint32_t pldm_pdr_get_record_handle(const pldm_pdr *repo,
111 const pldm_pdr_record *record);
112
113/** @brief Find PDR record by record handle
114 *
115 * @param[in] repo - opaque pointer acting as a PDR repo handle
116 * @param[in] record_handle - input record handle
117 * @param[in/out] data - will point to PDR record data (as per DSP0248) on
118 * return
119 * @param[out] size - *size will be size of PDR record
120 * @param[out] next_record_handle - *next_record_handle will be the record
121 * handle of record next to the returned PDR record
122 *
123 * @return opaque pointer acting as PDR record handle, will be NULL if record
124 * was not found
125 */
126const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo,
127 uint32_t record_handle,
128 uint8_t **data, uint32_t *size,
129 uint32_t *next_record_handle);
130
131/** @brief Get PDR record next to input PDR record
132 *
133 * @param[in] repo - opaque pointer acting as a PDR repo handle
134 * @param[in] curr_record - opaque pointer acting as a PDR record handle
135 * @param[in/out] data - will point to PDR record data (as per DSP0248) on
136 * return
137 * @param[out] size - *size will be size of PDR record
138 * @param[out] next_record_handle - *next_record_handle will be the record
139 * handle of record nect to the returned PDR record
140 *
141 * @return opaque pointer acting as PDR record handle, will be NULL if record
142 * was not found
143 */
144const pldm_pdr_record *
145pldm_pdr_get_next_record(const pldm_pdr *repo,
146 const pldm_pdr_record *curr_record, uint8_t **data,
147 uint32_t *size, uint32_t *next_record_handle);
148
149/** @brief Find (first) PDR record by PDR type
150 *
151 * @param[in] repo - opaque pointer acting as a PDR repo handle
152 * @param[in] pdr_type - PDR type number as per DSP0248
153 * @param[in] curr_record - opaque pointer acting as a PDR record handle; if
154 * not NULL, then search will begin from this record's next record
155 * @param[in/out] data - will point to PDR record data (as per DSP0248) on
156 * return, if input is not NULL
157 * @param[out] size - *size will be size of PDR record, if input is not NULL
158 *
159 * @return opaque pointer acting as PDR record handle, will be NULL if record
160 * was not found
161 */
162const pldm_pdr_record *
163pldm_pdr_find_record_by_type(const pldm_pdr *repo, uint8_t pdr_type,
164 const pldm_pdr_record *curr_record, uint8_t **data,
165 uint32_t *size);
166
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930167/** @brief Determine if a record is a remote record
168 *
169 * @pre record must point to a valid object
170 *
171 * @return true if the record is a remote record, false otherwise.
172 */
Andrew Jeffery9c766792022-08-10 23:12:49 +0930173bool pldm_pdr_record_is_remote(const pldm_pdr_record *record);
174
175/** @brief Remove all PDR records that belong to a remote terminus
176 *
177 * @param[in] repo - opaque pointer acting as a PDR repo handle
Andrew Jeffery3e1d6592023-07-03 11:57:16 +0930178 *
179 * If repo is NULL then there are no PDRs that can be removed.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930180 */
181void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo);
182
183/** @brief Remove all remote PDR's that beling to a specific terminus
184 * handle
185 * @param[in] repo - opaque pointer acting as a PDR repo handle
186 * @param[in] terminus_handle - Terminus Handle of the remove PLDM terminus
Andrew Jeffery438dd492023-07-03 11:51:43 +0930187 *
188 * If repo is NULL there are no PDRs that can be removed.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930189 */
190void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo,
191 uint16_t terminus_handle);
192
193/** @brief Update the validity of TL PDR - the validity is decided based on
194 * whether the valid bit is set or not as per the spec DSP0248
195 *
196 * @param[in] repo - opaque pointer acting as a PDR repo handle
Andrew Jeffery6005f1c2023-04-05 20:02:52 +0930197 * @param[in] terminus_handle - PLDM terminus handle
Andrew Jeffery9c766792022-08-10 23:12:49 +0930198 * @param[in] tid - Terminus ID
Andrew Jeffery2a38ab52023-04-06 15:09:08 +0930199 * @param[in] tl_eid - MCTP endpoint EID
Andrew Jeffery9c766792022-08-10 23:12:49 +0930200 * @param[in] valid - validity bit of TLPDR
201 */
Andrew Jeffery6005f1c2023-04-05 20:02:52 +0930202/* NOLINTNEXTLINE(readability-identifier-naming) */
203void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminus_handle,
204 uint8_t tid, uint8_t tl_eid, bool valid);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930205
Pavithra Barithaya4d694342023-05-19 08:04:41 -0500206/** @brief Find the last record within the particular range
207 * of record handles
208 *
209 * @param[in] repo - pointer acting as a PDR repo handle
210 * @param[in] first - first record handle value of the records in the range
211 * @param[in] last - last record handle value of the records in the range
212 *
213 * @return pointer to the PDR record,will be NULL if record was not
214 * found
215 */
216pldm_pdr_record *pldm_pdr_find_last_in_range(const pldm_pdr *repo,
217 uint32_t first, uint32_t last);
218
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500219/** @brief find the container ID of the contained entity which is not in the
220 * particular range of record handles given
221 *
222 * @param[in] repo - opaque pointer acting as a PDR repo handle
223 * @param[in] entity_type - entity type
224 * @param[in] entity_instance - instance of the entity
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500225 * @param[in] child_index - index of the child entity whose container id needs to be found
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500226 * @param[in] range_exclude_start_handle - first record handle in the range of the remote endpoint
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500227 * which is ignored
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500228 * @param[in] range_exclude_end_handle - last record handle in the range of the remote endpoint
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500229 * which is ignored
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500230 * @param[out] container_id - container id of the contained entity
231 *
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500232 * @return container id of the PDR record found on success,-EINVAL when repo is NULL
233 * or -ENOKEY if the container id is not found.
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500234 */
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500235int pldm_pdr_find_child_container_id_index_range_exclude(
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500236 const pldm_pdr *repo, uint16_t entity_type, uint16_t entity_instance,
Pavithra Barithaya8cf70452023-06-22 04:36:19 -0500237 uint8_t child_index, uint32_t range_exclude_start_handle,
238 uint32_t range_exclude_end_handle, uint16_t *container_id);
Pavithra Barithaya5dc02572023-05-19 09:24:36 -0500239
Andrew Jeffery9c766792022-08-10 23:12:49 +0930240/* ======================= */
241/* FRU Record Set PDR APIs */
242/* ======================= */
243
244/** @brief Add a FRU record set PDR record to a PDR repository
245 *
246 * @param[in/out] repo - opaque pointer acting as a PDR repo handle
247 * @param[in] terminus_handle - PLDM terminus handle of terminus owning the PDR
248 * record
249 * @param[in] fru_rsi - FRU record set identifier
250 * @param[in] entity_type - entity type of FRU
251 * @param[in] entity_instance_num - entity instance number of FRU
252 * @param[in] container_id - container id of FRU
253 * @param[in] bmc_record_handle - handle used to construct the next record
254 *
255 * @return uint32_t - record handle assigned to PDR record
256 */
257uint32_t pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle,
258 uint16_t fru_rsi, uint16_t entity_type,
259 uint16_t entity_instance_num,
260 uint16_t container_id,
261 uint32_t bmc_record_handle);
262
263/** @brief Find a FRU record set PDR by FRU record set identifier
264 *
265 * @param[in] repo - opaque pointer acting as a PDR repo handle
266 * @param[in] fru_rsi - FRU record set identifier
267 * @param[in] terminus_handle - *terminus_handle will be FRU terminus handle of
268 * found PDR, or 0 if not found
269 * @param[in] entity_type - *entity_type will be FRU entity type of found PDR,
270 * or 0 if not found
271 * @param[in] entity_instance_num - *entity_instance_num will be FRU entity
272 * instance number of found PDR, or 0 if not found
273 * @param[in] container_id - *cintainer_id will be FRU container id of found
274 * PDR, or 0 if not found
275 *
Andrew Jefferyaf7a4d82023-06-30 13:46:32 +0930276 * @return An opaque pointer to the PDR record on success, or NULL on failure
Andrew Jeffery9c766792022-08-10 23:12:49 +0930277 */
278const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930279 const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle,
280 uint16_t *entity_type, uint16_t *entity_instance_num,
281 uint16_t *container_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930282
283/* =========================== */
284/* Entity Association PDR APIs */
285/* =========================== */
286
287typedef struct pldm_entity {
288 uint16_t entity_type;
289 uint16_t entity_instance_num;
290 uint16_t entity_container_id;
291} __attribute__((packed)) pldm_entity;
292
293enum entity_association_containment_type {
294 PLDM_ENTITY_ASSOCIAION_PHYSICAL = 0x0,
295 PLDM_ENTITY_ASSOCIAION_LOGICAL = 0x1,
296};
297
298/** @struct pldm_entity_association_tree
299 * opaque structure that represents the entity association hierarchy
300 */
301typedef struct pldm_entity_association_tree pldm_entity_association_tree;
302
303/** @struct pldm_entity_node
304 * opaque structure that represents a node in the entity association hierarchy
305 */
306typedef struct pldm_entity_node pldm_entity_node;
307
308/** @brief Make a new entity association tree
309 *
310 * @return opaque pointer that acts as a handle to the tree; NULL if no
311 * tree could be created
312 */
Andrew Jeffery319304f2023-04-05 13:53:18 +0930313pldm_entity_association_tree *pldm_entity_association_tree_init(void);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930314
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500315/** @brief Add a local entity into the entity association tree
Andrew Jeffery9c766792022-08-10 23:12:49 +0930316 *
317 * @param[in/out] tree - opaque pointer acting as a handle to the tree
318 * @param[in/out] entity - pointer to the entity to be added. Input has the
319 * entity type. On output, instance number and the
320 * container id are populated.
321 * @param[in] entity_instance_number - entity instance number, we can use the
322 * entity instance number of the entity by
323 * default if its value is equal 0xFFFF.
324 * @param[in] parent - pointer to the node that should be the parent of input
325 * entity. If this is NULL, then the entity is the root
326 * @param[in] association_type - relation with the parent : logical or physical
327 *
328 * @return pldm_entity_node* - opaque pointer to added entity
329 */
330pldm_entity_node *pldm_entity_association_tree_add(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930331 pldm_entity_association_tree *tree, pldm_entity *entity,
332 uint16_t entity_instance_number, pldm_entity_node *parent,
333 uint8_t association_type);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930334
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500335/** @brief Add an entity into the entity association tree based on remote field
336 * set or unset.
337 *
338 * @param[in/out] tree - opaque pointer acting as a handle to the tree
339 * @param[in/out] entity - pointer to the entity to be added. Input has the
340 * entity type. On output, instance number and the
341 * container id are populated.
342 * @param[in] entity_instance_number - entity instance number, we can use the
343 * entity instance number of the entity by
344 * default if its value is equal 0xFFFF.
345 * @param[in] parent - pointer to the node that should be the parent of input
346 * entity. If this is NULL, then the entity is the root
347 * @param[in] association_type - relation with the parent : logical or physical
348 * @param[in] is_remote - used to denote whether we are adding a BMC entity to
349 * the tree or a host entity
350 * @param[in] is_update_contanier_id - Used to determine whether need to update
351 * contanier id.
352 * true: should be changed
353 * false: should not be changed
354 * @param[in] container_id - container id of the entity added.
355 *
356 * @return pldm_entity_node* - opaque pointer to added entity
357 */
358pldm_entity_node *pldm_entity_association_tree_add_entity(
359 pldm_entity_association_tree *tree, pldm_entity *entity,
360 uint16_t entity_instance_number, pldm_entity_node *parent,
361 uint8_t association_type, bool is_remote, bool is_update_container_id,
362 uint16_t container_id);
363
Andrew Jeffery9c766792022-08-10 23:12:49 +0930364/** @brief Visit and note each entity in the entity association tree
365 *
Andrew Jeffery8e9b0de2023-06-30 14:05:04 +0930366 * @pre `*entities == NULL` and `*size == 0` must hold at the time of invocation.
367 *
368 * Callers must inspect the values of `*entities` and `*size` post-invocation to determine if the
369 * invocation was a success or failure.
370 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930371 * @param[in] tree - opaque pointer acting as a handle to the tree
372 * @param[out] entities - pointer to list of pldm_entity's. To be free()'d by
373 * the caller
374 * @param[out] size - number of pldm_entity's
375 */
376void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree,
377 pldm_entity **entities, size_t *size);
378
379/** @brief Extract pldm entity by the pldm_entity_node
380 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930381 * @pre node must point to a valid object
382 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930383 * @param[in] node - opaque pointer to added entity
384 *
385 * @return pldm_entity - pldm entity
386 */
387pldm_entity pldm_entity_extract(pldm_entity_node *node);
388
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600389/** @brief Extract remote container id from the pldm_entity_node
390 *
Andrew Jeffery15b88182023-06-30 13:29:17 +0930391 * @pre entity must point to a valid object
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600392 *
Andrew Jeffery15b88182023-06-30 13:29:17 +0930393 * @param[in] entity - pointer to existing entity
394 *
395 * @return The remote container id
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600396 */
Andrew Jeffery15b88182023-06-30 13:29:17 +0930397uint16_t
398pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity);
ArchanaKakani39bd2ea2023-02-02 02:39:18 -0600399
Andrew Jeffery9c766792022-08-10 23:12:49 +0930400/** @brief Destroy entity association tree
401 *
402 * @param[in] tree - opaque pointer acting as a handle to the tree
403 */
404void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree);
405
406/** @brief Check if input enity node is a parent
407 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930408 * @pre node must point to a valid object
409 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930410 * @param[in] node - opaque pointer acting as a handle to an entity node
411 *
412 * @return bool true if node is a parent, false otherwise
413 */
414bool pldm_entity_is_node_parent(pldm_entity_node *node);
415
416/** @brief Get parent of entity
417 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930418 * @pre node must point to a valid object
419 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930420 * @param[in] node - opaque pointer acting as a handle to an entity node
421 *
422 * @return pldm_entity - pldm entity
423 */
424pldm_entity pldm_entity_get_parent(pldm_entity_node *node);
425
426/** @brief Check the current pldm entity is exist parent
427 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930428 * @pre node must point to a valid object
429 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930430 * @param[in] node - opaque pointer acting as a handle to an entity node
431 *
432 * @return bool true if exist parent, false otherwise
433 */
434bool pldm_entity_is_exist_parent(pldm_entity_node *node);
435
436/** @brief Convert entity association tree to PDR
437 *
Andrew Jefferyc7883482023-06-30 15:52:04 +0930438 * No conversion takes place if one or both of tree or repo are NULL.
439 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930440 * @param[in] tree - opaque pointer to entity association tree
441 * @param[in] repo - PDR repo where entity association records should be added
442 * @param[in] is_remote - if true, then the PDR is not from this terminus
443 * @param[in] terminus_handle - terminus handle of the terminus
444 */
445void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree,
446 pldm_pdr *repo, bool is_remote,
447 uint16_t terminus_handle);
Andrew Jefferycc394522023-07-03 12:49:31 +0930448
Andrew Jeffery9c766792022-08-10 23:12:49 +0930449/** @brief Add entity association pdr from node
450 *
451 * @param[in] node - opaque pointer acting as a handle to an entity node
452 * @param[in] repo - PDR repo where entity association records should be added
453 * @param[in] is_remote - if true, then the PDR is not from this terminus
454 * @param[in] terminus_handle - terminus handle of the terminus
455 */
456void pldm_entity_association_pdr_add_from_node(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930457 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities,
458 size_t num_entities, bool is_remote, uint16_t terminus_handle);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930459
Andrew Jefferycc394522023-07-03 12:49:31 +0930460/** @brief Add entity association pdr from node, or return an error
461 *
462 * @param[in] node - opaque pointer acting as a handle to an entity node
463 * @param[in] repo - PDR repo where entity association records should be added
464 * @param[in] is_remote - if true, then the PDR is not from this terminus
465 * @param[in] terminus_handle - terminus handle of the terminus
466 *
467 * @return 0 on success, -EINVAL if the provided arguments are invalid.
468 */
469int pldm_entity_association_pdr_add_from_node_check(
470 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities,
471 size_t num_entities, bool is_remote, uint16_t terminus_handle);
472
Pavithra Barithaya25ddbcc2023-05-19 08:28:59 -0500473/** @brief Add entity association pdr record based on record handle
474 * earlier the records where added in a sequential way alone, with
475 * this change the entity association PDR records gets the new record
476 * handle based on the input value given.
477 *
478 * @param[in] node - opaque pointer acting as a handle to an entity node
479 * @param[in] repo - PDR repo where entity association records should be added
480 * @param[in] is_remote - if true, then the PDR is not from this terminus
481 * @param[in] terminus_handle - terminus handle of the terminus
482 * @param[in] record_handle - record handle of the PDR
483 *
484 * @return 0 on succes, -EINVAL if the provided arguments are invalid.
485 */
486int pldm_entity_association_pdr_add_from_node_with_record_handle(
487 pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities,
488 size_t num_entities, bool is_remote, uint16_t terminus_handle,
489 uint32_t record_handle);
490
Andrew Jeffery9c766792022-08-10 23:12:49 +0930491/** @brief Find entity reference in tree
492 *
493 * @param[in] tree - opaque pointer to entity association tree
494 * @param[in] entity - PLDM entity
495 * @param[in] node - node to the entity
496 */
497void pldm_find_entity_ref_in_tree(pldm_entity_association_tree *tree,
498 pldm_entity entity, pldm_entity_node **node);
499
500/** @brief Get number of children of entity
501 *
502 * @param[in] node - opaque pointer acting as a handle to an entity node
503 * @param[in] association_type - relation type filter : logical or physical
504 *
Andrew Jeffery6e8a2612023-06-30 15:36:48 +0930505 * @return uint8_t number of children. The returned value is zero if node is NULL or
506 * association_type is not one of PLDM_ENTITY_ASSOCIAION_PHYSICAL or
507 * PLDM_ENTITY_ASSOCIAION_LOGICAL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930508 */
509uint8_t pldm_entity_get_num_children(pldm_entity_node *node,
510 uint8_t association_type);
511
512/** @brief Verify that the current node is a child of the current parent
513 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930514 * @pre parent must point to a valid object
515 * @pre node must point to a valid object
516 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930517 * @param[in] parent - opaque pointer acting as a handle to an entity parent
518 * @param[in] node - pointer to the node of the pldm entity
Andrew Jeffery375d9fc2023-06-30 15:45:54 +0930519 *
520 * @return True if the node is a child of parent, false otherwise, including if one or both of
521 * parent or node are NULL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930522 */
523bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node);
524
525/** @brief Find an entity in the entity association tree
526 *
527 * @param[in] tree - pointer to entity association tree
528 * @param[in/out] entity - entity type and instance id set on input, container
529 * id set on output
Andrew Jeffery9c766792022-08-10 23:12:49 +0930530 * @return pldm_entity_node* pointer to entity if found, NULL otherwise
Andrew Jeffery94e364d2023-07-03 12:26:59 +0930531 *
532 * There are no entity nodes to search if tree is NULL, nor are there entity nodes to find if the
533 * search criteria are unspecified when entity is NULL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930534 */
535pldm_entity_node *
536pldm_entity_association_tree_find(pldm_entity_association_tree *tree,
537 pldm_entity *entity);
538
Pavithra Barithaya9947f9d2023-05-18 05:20:24 -0500539/** @brief Find an entity in the entity association tree if remote
540 *
541 * @param[in] tree - pointer to entity association tree
542 * @param[in/out] entity - entity type and instance id set on input, container
543 * id set on output
544 * @param[in] is_remote - variable to denote whether we are finding a host
545 * entity or a BMC entity
546 *
547 * @return pldm_entity_node* pointer to entity if found, NULL otherwise
548 */
549pldm_entity_node *
550pldm_entity_association_tree_find_if_remote(pldm_entity_association_tree *tree,
551 pldm_entity *entity,
552 bool is_remote);
553
Andrew Jeffery9c766792022-08-10 23:12:49 +0930554/** @brief Create a copy of an existing entity association tree
555 *
556 * @param[in] org_tree - pointer to source tree
557 * @param[in/out] new_tree - pointer to destination tree
558 */
559void pldm_entity_association_tree_copy_root(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930560 pldm_entity_association_tree *org_tree,
561 pldm_entity_association_tree *new_tree);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930562
563/** @brief Destroy all the nodes of the entity association tree
564 *
565 * @param[in] tree - pointer to entity association tree
Andrew Jeffery85d7a052023-07-03 12:29:24 +0930566 *
567 * There is no tree to destroy if tree is NULL.
Andrew Jeffery9c766792022-08-10 23:12:49 +0930568 */
569void pldm_entity_association_tree_destroy_root(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930570 pldm_entity_association_tree *tree);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930571
572/** @brief Check whether the entity association tree is empty
573 *
Andrew Jeffery5565fcd2023-06-30 13:21:32 +0930574 * @pre tree must point to a valid object
575 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930576 * @param[in] tree - pointer to entity association tree
577 * @return bool, true if tree is empty
578 */
579bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree);
580
581/** @brief Extract entities from entity association PDR
582 *
Andrew Jeffery3a5c46b2023-07-03 12:39:59 +0930583 * @pre `*entities == NULL` and `*num_entities == 0` must hold at the time of invocation.
584 *
Andrew Jeffery9c766792022-08-10 23:12:49 +0930585 * @param[in] pdr - entity association PDR
586 * @param[in] pdr_len - size of entity association PDR in bytes
587 * @param[out] num_entities - number of entities found, including the container
588 * @param[out] entities - extracted entities, container is *entities[0]. Caller
589 * must free *entities
590 */
591void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len,
592 size_t *num_entities,
593 pldm_entity **entities);
594
595#ifdef __cplusplus
596}
597#endif
598
599#endif /* PDR_H */