From 81d781fd4739a8fa5fa662cd4fe58ba32c21af56 Mon Sep 17 00:00:00 2001 From: ManojKiran Eda Date: Fri, 20 Jan 2023 21:39:14 +0530 Subject: [PATCH] 1050: Master rebase with GHE patches (#4) Signed-off-by: Manojkiran Eda Signed-off-by: Manojkiran Eda --- include/libpldm/meson.build | 2 + include/libpldm/oem/ibm/libpldm/file_io.h | 10 + include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h | 2 + include/libpldm/oem/ibm/libpldm/pdr_oem_ibm.h | 42 + .../oem/ibm/libpldm/state_set_oem_ibm.h | 30 + include/libpldm/pdr.h | 216 ++- include/libpldm/pdr_data.h | 41 + include/libpldm/platform.h | 11 +- include/libpldm/pldm_types.h | 6 +- include/libpldm/state_set.h | 10 +- include/libpldm/states.h | 6 + src/meson.build | 2 + src/oem/ibm/meson.build | 3 +- src/oem/ibm/pdr.c | 69 + src/pdr.c | 1220 +++++++++++++++-- tests/libpldm_pdr_test.cpp | 484 +++++-- tests/libpldm_utils_test.cpp | 14 +- 17 files changed, 1923 insertions(+), 245 deletions(-) create mode 100755 include/libpldm/oem/ibm/libpldm/pdr_oem_ibm.h create mode 100755 include/libpldm/pdr_data.h create mode 100644 src/oem/ibm/pdr.c diff --git a/include/libpldm/meson.build b/include/libpldm/meson.build index 0d25754a1..c1da29d0d 100644 --- a/include/libpldm/meson.build +++ b/include/libpldm/meson.build @@ -11,6 +11,7 @@ libpldm_headers += files( 'state_set.h', 'fru.h', 'utils.h', + 'pdr_data.h', 'pdr.h', 'firmware_update.h' ) @@ -23,6 +24,7 @@ if get_option('oem-ibm').enabled() 'oem/ibm/libpldm/host.h', 'oem/ibm/libpldm/fru_oem_ibm.h', 'oem/ibm/libpldm/platform_oem_ibm.h', + 'oem/ibm/libpldm/pdr_oem_ibm.h', 'oem/ibm/libpldm/state_set_oem_ibm.h' ) endif diff --git a/include/libpldm/oem/ibm/libpldm/file_io.h b/include/libpldm/oem/ibm/libpldm/file_io.h index 10963bcf1..272374d2b 100644 --- a/include/libpldm/oem/ibm/libpldm/file_io.h +++ b/include/libpldm/oem/ibm/libpldm/file_io.h @@ -59,7 +59,17 @@ enum pldm_fileio_file_type { PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS = 0x8, PLDM_FILE_TYPE_RESOURCE_DUMP = 0x9, PLDM_FILE_TYPE_PROGRESS_SRC = 0xA, + PLDM_FILE_TYPE_ADJUNCT_DUMP = 0xB, + PLDM_FILE_TYPE_DEVICE_DUMP = 0xC, + PLDM_FILE_TYPE_COD_LICENSE_KEY = 0xD, + PLDM_FILE_TYPE_COD_LICENSED_RESOURCES = 0xE, + PLDM_FILE_TYPE_BMC_DUMP = 0xF, + PLDM_FILE_TYPE_SBE_DUMP = 0x10, + PLDM_FILE_TYPE_HOSTBOOT_DUMP = 0x11, + PLDM_FILE_TYPE_HARDWARE_DUMP = 0x12, PLDM_FILE_TYPE_LID_RUNNING = 0x13, + PLDM_FILE_TYPE_PCIE_TOPOLOGY = 0x14, + PLDM_FILE_TYPE_CABLE_INFO = 0x15, }; #define PLDM_RW_FILE_MEM_REQ_BYTES 20 diff --git a/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h index c97f8b080..22df9ad83 100644 --- a/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h +++ b/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h @@ -12,6 +12,8 @@ enum pldm_oem_ibm_fru_field_type { PLDM_OEM_FRU_FIELD_TYPE_IANA = 0X01, PLDM_OEM_FRU_FIELD_TYPE_RT = 0X02, PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE = 0XFE, + PLDM_OEM_FRU_FIELD_TYPE_PCIE_CONFIG_SPACE_DATA = 0XFD, + PLDM_OEM_FRU_FIELD_TYPE_FIRMWARE_UAK = 0XFC, }; #ifdef __cplusplus diff --git a/include/libpldm/oem/ibm/libpldm/pdr_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/pdr_oem_ibm.h new file mode 100755 index 000000000..f46c1bbf2 --- /dev/null +++ b/include/libpldm/oem/ibm/libpldm/pdr_oem_ibm.h @@ -0,0 +1,42 @@ +#ifndef PDR_OEM_IBM_H +#define PDR_OEM_IBM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "pdr_data.h" +#include "platform.h" +#include +#include +#include + +/** @brief Find the last local record + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * + * @return opaque pointer to the PDR record,will be NULL if record was not + * found + */ +pldm_pdr_record *pldm_pdr_find_last_local_record(const pldm_pdr *repo); + +/** @brief method to check if the record handle is within the HostBoot range + * or not + * + * @param[in] record_handle - record handle of the pdr + */ +bool isHBRange(const uint32_t record_handle); + +/** @brief find the container ID of the contained entity + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] entityType - entity type + * @param[in] entityInstance - instance of the entity + */ +uint16_t pldm_find_container_id(const pldm_pdr *repo, uint16_t entityType, + uint16_t entityInstance); +#ifdef __cplusplus +} +#endif + +#endif /* PDR_OEM_IBM_H */ diff --git a/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h index 5c8378b5c..09f3b726e 100644 --- a/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h +++ b/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h @@ -12,7 +12,27 @@ enum ibm_oem_pldm_state_set_ids { PLDM_OEM_IBM_VERIFICATION_STATE = 32770, PLDM_OEM_IBM_SYSTEM_POWER_STATE = 32771, PLDM_OEM_IBM_SBE_MAINTENANCE_STATE = 32772, + PLDM_OEM_IBM_BOOT_SIDE_RENAME = 32773, + PLDM_OEM_IBM_SBE_SEMANTIC_ID = 32775, PLDM_OEM_IBM_SBE_HRESET_STATE = 32776, + + PLDM_OEM_IBM_PANEL_TRIGGER_STATE = 32778, + PLDM_OEM_IBM_SLOT_ENABLE_EFFECTER_STATE = 32779, + PLDM_OEM_IBM_SLOT_ENABLE_SENSOR_STATE = 32780, + PLDM_OEM_IBM_PCIE_TOPOLOGY_ACTIONS = 32781, +}; + +enum ibm_slot_enable_effecter_state { + ADD = 0x1, + REMOVE = 0x2, + REPLACE = 0x3, +}; + +enum ibm_slot_enable_sensor_state { + SLOT_STATE_UNKOWN = 0x0, + SLOT_STATE_ENABLED = 0x1, + SLOT_STATE_DISABLED = 0x2, + SLOT_STATE_ERROR = 0x03, }; enum ibm_oem_pldm_state_set_firmware_update_state_values { @@ -45,12 +65,22 @@ enum ibm_oem_pldm_state_set_sbe_dump_state_values { SBE_RETRY_REQUIRED = 0x2, }; +enum ibm_oem_pldm_state_set_boot_side_rename_state_values { + PLDM_BOOT_SIDE_NOT_RENAMED = 1, + PLDM_BOOT_SIDE_HAS_BEEN_RENAMED = 2, +}; enum ibm_oem_pldm_state_set_sbe_hreset_state_values { SBE_HRESET_NOT_READY = 0x1, SBE_HRESET_READY = 0x2, SBE_HRESET_FAILED = 0x3, }; +enum pldm_oem_pcie_topology_actions { + GET_PCIE_TOPOLOGY = 0x1, + GET_CABLE_INFO = 0x2, + SAVE_PCIE_TOPLOGY = 0x03, +}; + #ifdef __cplusplus } #endif diff --git a/include/libpldm/pdr.h b/include/libpldm/pdr.h index 671b72692..125998e47 100644 --- a/include/libpldm/pdr.h +++ b/include/libpldm/pdr.h @@ -9,15 +9,7 @@ extern "C" { #include #include -/** @struct pldm_pdr - * opaque structure that acts as a handle to a PDR repository - */ -typedef struct pldm_pdr pldm_pdr; - -/** @struct pldm_pdr_record - * opaque structure that acts as a handle to a PDR record - */ -typedef struct pldm_pdr_record pldm_pdr_record; +#include "pdr_data.h" /* ====================== */ /* Common PDR access APIs */ @@ -73,6 +65,29 @@ uint32_t pldm_pdr_add(pldm_pdr *repo, const uint8_t *data, uint32_t size, uint32_t record_handle, bool is_remote, uint16_t terminus_handle); +uint32_t pldm_pdr_add_hotplug_record(pldm_pdr *repo, const uint8_t *data, + uint32_t size, uint32_t record_handle, + bool is_remote, + uint32_t prev_record_handle, + uint16_t terminus_handle); +/** @brief Add a PDR record after the record handle sent as input + * + * @param[in/out] repo - opaque pointer acting as a PDR repo handle + * @param[in] data - pointer to a PDR record, pointing to a PDR definition as + * per DSP0248. This data is memcpy'd. + * @param[in] size - size of input PDR record in bytes + * @param[in] record_handle - record handle of input PDR record + * @param[in] is_remote - if true, then the PDR is not from this terminus + * @param[in] prev_record_handle - the record handle after which the input + * record handle should be added in the repo + * + * @return uint32_t - record handle assigned to PDR record*/ +uint32_t pldm_pdr_add_after_prev_record(pldm_pdr *repo, const uint8_t *data, + uint32_t size, uint32_t record_handle, + bool is_remote, + uint32_t prev_record_handle, + uint16_t terminus_handle); + /** @brief Get record handle of a PDR record * * @param[in] repo - opaque pointer acting as a PDR repo handle @@ -102,6 +117,18 @@ const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo, uint8_t **data, uint32_t *size, uint32_t *next_record_handle); +/** @brief Find the previous record handle of a PDR record + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] record_handle - record handle of input PDR record + * @param[out] prev_record_handle - record handle of the previous + * PDR + * + * @return true if record found, false otherwise + */ +bool pldm_pdr_find_prev_record_handle(pldm_pdr *repo, uint32_t record_handle, + uint32_t *prev_record_handle); + /** @brief Get PDR record next to input PDR record * * @param[in] repo - opaque pointer acting as a PDR repo handle @@ -165,6 +192,70 @@ void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo, */ void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminusHandle, uint8_t tid, uint8_t tlEid, bool valid); +/** @brief Delete record using its record handle + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] record_handle - record handle of input PDR record + * @param[in] is_remote - if true, then the PDR is not from this terminus + */ +void pldm_delete_by_record_handle(pldm_pdr *repo, uint32_t record_handle, + bool is_remote); + +/** @brief update the container id of an effecter + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] effecterId - effecter ID + * @param[in] containerId - conatiner ID to be updated + */ +void pldm_change_container_id_of_effecter(const pldm_pdr *repo, + uint16_t effecterId, + uint16_t containerId); + +/** @brief update the container id of a sensor + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] sensorId - sensor ID + * @param[in] containerId - conatiner ID to be updated + */ +void pldm_change_container_id_of_sensor(const pldm_pdr *repo, uint16_t sensorId, + uint16_t containerId); + +/** @brief update the instance number of an effecter + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] effecterId - effecter ID + * @param[in] instanceNumber - instance number to be updated + */ +void pldm_change_instance_number_of_effecter(const pldm_pdr *repo, + uint16_t effecterId, + uint16_t instanceNumber); + +/** @brief update the instance number of a sensor + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] sensorId - sensor ID + * @param[in] instanceNumber - instance number to be updated + */ +void pldm_change_instance_number_of_sensor(const pldm_pdr *repo, + uint16_t sensorId, + uint16_t instanceNumber); +/** @brief delete the pdr by effecter id + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] effecter_id - effecter ID + * @param[in] is_remote - indicates which PDR to remove, local or remote + */ +uint16_t pldm_delete_by_effecter_id(pldm_pdr *repo, uint16_t effecter_id, + bool is_remote); + +/** @brief delete the pdr by sensor id + * + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] sensor_id - sensor ID + * @param[in] is_remote - indicates which PDR to remove, local or remote + */ +uint16_t pldm_delete_by_sensor_id(pldm_pdr *repo, uint16_t sensor_id, + bool is_remote); /* ======================= */ /* FRU Record Set PDR APIs */ @@ -180,6 +271,7 @@ void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminusHandle, * @param[in] entity_instance_num - entity instance number of FRU * @param[in] container_id - container id of FRU * @param[in] bmc_record_handle - handle used to construct the next record + * @param[in] hotplug - indicates if its a hotplug PDR or not * * @return uint32_t - record handle assigned to PDR record */ @@ -187,7 +279,7 @@ uint32_t pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle, uint16_t fru_rsi, uint16_t entity_type, uint16_t entity_instance_num, uint16_t container_id, - uint32_t bmc_record_handle); + uint32_t bmc_record_handle, bool hotplug); /** @brief Find a FRU record set PDR by FRU record set identifier * @@ -201,13 +293,24 @@ uint32_t pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle, * instance number of found PDR, or 0 if not found * @param[in] container_id - *cintainer_id will be FRU container id of found * PDR, or 0 if not found + * @param[in] is_remote - indicates which PDR to search * * @return uint32_t - record handle assigned to PDR record */ const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle, uint16_t *entity_type, uint16_t *entity_instance_num, - uint16_t *container_id); + uint16_t *container_id, bool is_remote); + +/** @brief deletes a FRU record set PDR by FRU record set identifier + * @param[in] repo - opaque pointer acting as a PDR repo handle + * @param[in] fru_rsi - FRU record set identifier + * @param[in] is_remote - indicates which PDR to remove, local or remote + * + * @return uint32_t the FRU rsi that was removed + */ +uint32_t pldm_pdr_remove_fru_record_set_by_rsi(pldm_pdr *repo, uint16_t fru_rsi, + bool is_remote); /* =========================== */ /* Entity Association PDR APIs */ @@ -241,6 +344,14 @@ typedef struct pldm_entity_node pldm_entity_node; */ pldm_entity_association_tree *pldm_entity_association_tree_init(); +/** @brief Next Container ID from the association tree + * + * @param[in] tree - opaque pointer acting as a handle to the tree + * + * @return next container id - container id of the entity + */ +uint16_t next_container_id(pldm_entity_association_tree *tree); + /** @brief Add an entity into the entity association tree * * @param[in/out] tree - opaque pointer acting as a handle to the tree @@ -254,12 +365,30 @@ pldm_entity_association_tree *pldm_entity_association_tree_init(); * entity. If this is NULL, then the entity is the root * @param[in] association_type - relation with the parent : logical or physical * + * @param[in] is_remote - used to denote whether we are adding a BMC entity to + * the tree or a host entity + * @param[in] is_update_contanier_id - Used to determine whether need to update + * contanier id. + * true: should be changed + * false: should not be changed + * @param[in] conatiner_id - container id of the entity added + * * @return pldm_entity_node* - opaque pointer to added entity */ pldm_entity_node *pldm_entity_association_tree_add( pldm_entity_association_tree *tree, pldm_entity *entity, uint16_t entity_instance_number, pldm_entity_node *parent, - uint8_t association_type); + uint8_t association_type, bool is_remote, bool is_update_contanier_id, + uint16_t container_id); + +/** @brief deletes a node and it's children from the entity association tree + * @param[in] tree - opaque pointer acting as a handle to the tree + * @param[in] entity - the pldm entity to be deleted + * + * @return none + */ +void pldm_entity_association_tree_delete_node( + pldm_entity_association_tree *tree, pldm_entity entity); /** @brief Visit and note each entity in the entity association tree * @@ -279,6 +408,14 @@ void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree, */ pldm_entity pldm_entity_extract(pldm_entity_node *node); +/** @brief Extract host container id by the pldm_entity_node + * + * @param[in] entity - opaque pointer to added entity + * + * @return host container id - host container id + */ +uint16_t pldm_extract_host_container_id(const pldm_entity_node *entity); + /** @brief Destroy entity association tree * * @param[in] tree - opaque pointer acting as a handle to the tree @@ -325,10 +462,42 @@ void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree, * @param[in] repo - PDR repo where entity association records should be added * @param[in] is_remote - if true, then the PDR is not from this terminus * @param[in] terminus_handle - terminus handle of the terminus + * @param[in] record_handle - is used to decide in which range pdr will be + * added 0 - Added next to recently added PDR in the repository 0xFFFFFFFF - + * Added in BMC range */ void pldm_entity_association_pdr_add_from_node( pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities, - size_t num_entities, bool is_remote, uint16_t terminus_handle); + size_t num_entities, bool is_remote, uint16_t terminus_handle, + uint32_t record_handle); + +/** @brief Remove a contained entity from an entity association PDR + * @param[in] repo - opaque pointer to pldm PDR repo + * @param[in] entity - the pldm entity to be deleted + * @param[in] event_data_op - the event data operation that happens on the + * record + * @param[in] is_remote - whether to delete from a remote pDR or local PDR + * + * @return uint32_t the PDR record handle that was updated + */ +uint32_t pldm_entity_association_pdr_remove_contained_entity( + pldm_pdr *repo, pldm_entity entity, uint8_t *event_data_op, bool is_remote); + +/** @brief Add a contained entity into an entity association PDR + * @param[in] repo - opaque pointer to pldm PDR repo + * @param[in] entity - the pldm entity to be added + * @param[in] parent - the parent entity + * @param[in] event_data_op - the event data operation that happens on the + * record + * @param[in] is_remote - whether to add in the local or remote PDR + * + * @param[in] bmc_record_handle - handle to be added to the pdr + * + * @return uint32_t the updated PDR record handle + */ +uint32_t pldm_entity_association_pdr_add_contained_entity( + pldm_pdr *repo, pldm_entity entity, pldm_entity parent, + uint8_t *event_data_op, bool is_remote, uint32_t bmc_record_handle); /** @brief Find entity reference in tree * @@ -361,12 +530,14 @@ bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node); * @param[in] tree - pointer to entity association tree * @param[in/out] entity - entity type and instance id set on input, container * id set on output + * @param[in] is_remote - variable to denote whether we are finding a host + * entity or a BMC entity * * @return pldm_entity_node* pointer to entity if found, NULL otherwise */ pldm_entity_node * pldm_entity_association_tree_find(pldm_entity_association_tree *tree, - pldm_entity *entity); + pldm_entity *entity, bool is_remote); /** @brief Create a copy of an existing entity association tree * @@ -402,6 +573,23 @@ bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree); void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len, size_t *num_entities, pldm_entity **entities); +pldm_entity pldm_get_entity_from_record_handle(const pldm_pdr *repo, + uint32_t record_handle); + +/** @brief Initialize the pldm_entity_node structure, just for deserialization + * + * @param[in] entity - node of pldm entity + * @param[in] parent - parent of pldm entity + * @param[in] host_container_id - host container id + * @param[in] first_child - first child of pldm entity + * @param[in] next_sibling - net sibling of pldm entity + * @param[in] association_type - association type + */ +pldm_entity_node *init_pldm_entity_node(pldm_entity entity, pldm_entity parent, + uint16_t host_container_id, + pldm_entity_node *first_child, + pldm_entity_node *next_sibling, + uint8_t association_type); #ifdef __cplusplus } diff --git a/include/libpldm/pdr_data.h b/include/libpldm/pdr_data.h new file mode 100755 index 000000000..ec66caaf7 --- /dev/null +++ b/include/libpldm/pdr_data.h @@ -0,0 +1,41 @@ +#ifndef PDR_DATA_H +#define PDR_DATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef struct pldm_pdr_record { + uint32_t record_handle; + uint32_t size; + uint8_t *data; + struct pldm_pdr_record *next; + bool is_remote; + uint16_t terminus_handle; +} pldm_pdr_record; + +typedef struct pldm_pdr { + uint32_t record_count; + uint32_t size; + pldm_pdr_record *first; + pldm_pdr_record *last; +} pldm_pdr; + +/** @struct pldm_pdr + * * opaque structure that acts as a handle to a PDR repository + * */ +typedef struct pldm_pdr pldm_pdr; + +/** @struct pldm_pdr_record + * * opaque structure that acts as a handle to a PDR record + * */ +typedef struct pldm_pdr_record pldm_pdr_record; +#ifdef __cplusplus +} +#endif + +#endif /* PDR_DATA_H */ diff --git a/include/libpldm/platform.h b/include/libpldm/platform.h index 5e1a3dcec..2a3a10bb2 100644 --- a/include/libpldm/platform.h +++ b/include/libpldm/platform.h @@ -102,6 +102,12 @@ enum pldm_sensor_present_state { PLDM_SENSOR_UPPERFATAL = 0x0a }; +enum pldm_operational_fault_status { + PLDM_OPERATIONAL_NORMAL = 0x1, + PLDM_OPERATIONAL_ERROR = 0x2, + PLDM_OPERATIONAL_NON_RECOVERABLE_ERROR = 0x3 +}; + enum pldm_sensor_event_message_enable { PLDM_NO_EVENT_GENERATION, PLDM_EVENTS_DISABLED, @@ -243,7 +249,8 @@ enum pldm_pdr_repository_chg_event_change_record_event_data_operation { PLDM_REFRESH_ALL_RECORDS, PLDM_RECORDS_DELETED, PLDM_RECORDS_ADDED, - PLDM_RECORDS_MODIFIED + PLDM_RECORDS_MODIFIED, + PLDM_INVALID_OP }; /** @brief PLDM NumericSensorStatePresentReading data type @@ -473,7 +480,7 @@ struct pldm_pdr_fru_record_set { uint16_t terminus_handle; uint16_t fru_rsi; uint16_t entity_type; - uint16_t entity_instance_num; + uint16_t entity_instance; uint16_t container_id; } __attribute__((packed)); diff --git a/include/libpldm/pldm_types.h b/include/libpldm/pldm_types.h index e48cb8c38..3c5f08642 100644 --- a/include/libpldm/pldm_types.h +++ b/include/libpldm/pldm_types.h @@ -22,10 +22,10 @@ typedef union { * */ typedef struct pldm_version { - uint8_t alpha; - uint8_t update; - uint8_t minor; uint8_t major; + uint8_t minor; + uint8_t update; + uint8_t alpha; } __attribute__((packed)) ver32_t; typedef uint8_t bool8_t; diff --git a/include/libpldm/state_set.h b/include/libpldm/state_set.h index 23fd91c38..a16e7aa81 100644 --- a/include/libpldm/state_set.h +++ b/include/libpldm/state_set.h @@ -222,7 +222,15 @@ enum pldm_state_set_boot_progress_state_values { /* @brief List of states for the System Power State set (ID 260). */ enum pldm_state_set_system_power_state_values { - PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL = 9 + PLDM_STATE_SET_SYS_POWER_CYCLE_OFF_SOFT_GRACEFUL = 7, + PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL = 9, + PLDM_STATE_SET_SYS_POWER_STATE_OFF_HARD_GRACEFUL = 10, +}; + +enum pldm_state_set_device_power_state_values { + PLDM_STATE_SET_DEVICE_POWER_STATE_UNKNOWN = 0, + PLDM_STATE_SET_DEVICE_POWER_STATE_FULLY_ON = 1, + PLDM_STATE_SET_DEVICE_POWER_STATE_OFF = 4, }; /* OEM ranges */ diff --git a/include/libpldm/states.h b/include/libpldm/states.h index a89648dfa..f42af7904 100644 --- a/include/libpldm/states.h +++ b/include/libpldm/states.h @@ -20,6 +20,12 @@ enum pldm_system_power_states { PLDM_OFF_SOFT_GRACEFUL = 9, }; +/** @brief PLDM enums for availability states + */ +enum pldm_availability_states { + PLDM_RESETTING = 9, +}; + #ifdef __cplusplus } #endif diff --git a/src/meson.build b/src/meson.build index fc44e8a65..b8fd13784 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,6 +11,8 @@ libpldm_sources += files( ) if get_option('oem-ibm').enabled() + add_project_arguments('-DOEM_IBM', language : 'c') + add_project_arguments('-DOEM_IBM', language : 'cpp') subdir('oem/ibm') endif diff --git a/src/oem/ibm/meson.build b/src/oem/ibm/meson.build index 04bb24f19..47db31e7b 100644 --- a/src/oem/ibm/meson.build +++ b/src/oem/ibm/meson.build @@ -1,5 +1,6 @@ libpldm_sources += files( 'file_io.c', 'host.c', - 'platform.c' + 'platform.c', + 'pdr.c' ) diff --git a/src/oem/ibm/pdr.c b/src/oem/ibm/pdr.c new file mode 100644 index 000000000..2b48f2e0a --- /dev/null +++ b/src/oem/ibm/pdr.c @@ -0,0 +1,69 @@ +#include "libpldm/pdr.h" +#include "libpldm/pdr_oem_ibm.h" + +#include + +pldm_pdr_record *pldm_pdr_find_last_local_record(const pldm_pdr *repo) +{ + assert(repo != NULL); + pldm_pdr_record *curr = repo->first; + pldm_pdr_record *prev = repo->first; + pldm_pdr_record *record = curr; + uint32_t recent_record_handle = curr->record_handle; + + while (curr != NULL) { + if ((curr->record_handle > 0x00000000) && + (curr->record_handle < 0x00FFFFFF)) { + if (recent_record_handle < curr->record_handle) { + recent_record_handle = curr->record_handle; + record = curr; + } + } + prev = curr; + curr = curr->next; + } + if (curr == NULL && prev != NULL) { + return record; + } + return NULL; +} + +bool isHBRange(const uint32_t record_handle) +{ + if (record_handle >= 0x01000000 && record_handle < 0x01FFFFFF) { + return true; + } + return false; +} + +uint16_t pldm_find_container_id(const pldm_pdr *repo, uint16_t entityType, + uint16_t entityInstance) +{ + assert(repo != NULL); + + pldm_pdr_record *record = repo->first; + + while (record != NULL) { + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (hdr->type == PLDM_PDR_ENTITY_ASSOCIATION && + !(isHBRange(record->record_handle))) { + struct pldm_pdr_entity_association *pdr = + (struct pldm_pdr_entity_association + *)((uint8_t *)record->data + + sizeof(struct pldm_pdr_hdr)); + struct pldm_entity *child = + (struct pldm_entity *)(&pdr->children[0]); + for (int i = 0; i < pdr->num_children; ++i) { + if (pdr->container.entity_type == entityType && + pdr->container.entity_instance_num == + entityInstance) { + uint16_t id = + child->entity_container_id; + return id; + } + } + } + record = record->next; + } + return 0; +} diff --git a/src/pdr.c b/src/pdr.c index fe28aa920..46a55b70f 100644 --- a/src/pdr.c +++ b/src/pdr.c @@ -5,21 +5,11 @@ #include #include -typedef struct pldm_pdr_record { - uint32_t record_handle; - uint32_t size; - uint8_t *data; - struct pldm_pdr_record *next; - bool is_remote; - uint16_t terminus_handle; -} pldm_pdr_record; - -typedef struct pldm_pdr { - uint32_t record_count; - uint32_t size; - pldm_pdr_record *first; - pldm_pdr_record *last; -} pldm_pdr; +#include + +#ifdef OEM_IBM +#include "oem/ibm/libpldm/pdr_oem_ibm.h" +#endif static inline uint32_t get_next_record_handle(const pldm_pdr *repo, const pldm_pdr_record *record) @@ -50,6 +40,84 @@ static void add_record(pldm_pdr *repo, pldm_pdr_record *record) ++repo->record_count; } +static void add_hotplug_record(pldm_pdr *repo, pldm_pdr_record *record, + uint32_t prev_record_handle) +{ + // the new record + // needs to be added after prev_record_handle + assert(repo != NULL); + assert(record != NULL); + record->next = NULL; + bool recordAdded = false; + if (repo->first == NULL) { + assert(repo->last == NULL); + repo->first = record; + repo->last = record; + recordAdded = true; + } else { + pldm_pdr_record *curr = repo->first; + while (curr != NULL) { + if (curr->record_handle == prev_record_handle) { + record->next = curr->next; + curr->next = record; + if (record->next == NULL) { + repo->last->next = record; + repo->last = record; + } + recordAdded = true; + break; + } + curr = curr->next; + } + // printf("\nadding the fru hotplug here + // curr->record_handle=%d",curr->record_handle); + // printf("repo-last=%x, curr=%x, curr-next=%x",(unsigned + // int)repo->last, (unsigned int)curr, (unsigned + // int)curr->next); + } + if (recordAdded == false) { + free(record); + assert(recordAdded != false); + } + repo->size += record->size; + ++repo->record_count; +} + +static void add_record_after_record_handle(pldm_pdr *repo, + pldm_pdr_record *record, + uint32_t prev_record_handle) +{ + assert(repo != NULL); + assert(record != NULL); + bool recordAdded = false; + if (repo->first == NULL) { + assert(repo->last == NULL); + repo->first = record; + repo->last = record; + recordAdded = true; + } else { + pldm_pdr_record *curr = repo->first; + while (curr != NULL) { + if (curr->record_handle == prev_record_handle) { + record->next = curr->next; + curr->next = record; + if (record->next == NULL) { + repo->last = record; + } + recordAdded = true; + break; + } + curr = curr->next; + } + } + if (recordAdded == false) { + free(record); + assert(recordAdded != false); + } + repo->size += record->size; + ++repo->record_count; +} + static inline uint32_t get_new_record_handle(const pldm_pdr *repo) { assert(repo != NULL); @@ -70,8 +138,18 @@ static pldm_pdr_record *make_new_record(const pldm_pdr *repo, pldm_pdr_record *record = malloc(sizeof(pldm_pdr_record)); assert(record != NULL); - record->record_handle = - record_handle == 0 ? get_new_record_handle(repo) : record_handle; + if (record_handle == 0) { + record->record_handle = get_new_record_handle(repo); + } +#ifdef OEM_IBM + else if (record_handle == 0xFFFFFFFF) { + pldm_pdr_record *rec = pldm_pdr_find_last_local_record(repo); + record->record_handle = rec->record_handle + 1; + } +#endif + else { + record->record_handle = record_handle; + } record->size = size; record->is_remote = is_remote; record->terminus_handle = terminus_handle; @@ -85,11 +163,9 @@ static pldm_pdr_record *make_new_record(const pldm_pdr *repo, * caller supplied the record handle, it would exist in the * header already. */ - if (!record_handle) { - struct pldm_pdr_hdr *hdr = - (struct pldm_pdr_hdr *)(record->data); - hdr->record_handle = htole32(record->record_handle); - } + struct pldm_pdr_hdr *hdr = + (struct pldm_pdr_hdr *)(record->data); + hdr->record_handle = htole32(record->record_handle); } record->next = NULL; @@ -110,6 +186,37 @@ uint32_t pldm_pdr_add(pldm_pdr *repo, const uint8_t *data, uint32_t size, return record->record_handle; } +uint32_t pldm_pdr_add_hotplug_record(pldm_pdr *repo, const uint8_t *data, + uint32_t size, uint32_t record_handle, + bool is_remote, + uint32_t prev_record_handle, + uint16_t terminus_handle) +{ + assert(size != 0); + assert(data != NULL); + + pldm_pdr_record *record = make_new_record( + repo, data, size, record_handle, is_remote, terminus_handle); + add_hotplug_record(repo, record, prev_record_handle); + return record->record_handle; +} + +uint32_t pldm_pdr_add_after_prev_record(pldm_pdr *repo, const uint8_t *data, + uint32_t size, uint32_t record_handle, + bool is_remote, + uint32_t prev_record_handle, + uint16_t terminus_handle) +{ + assert(size != 0); + assert(data != NULL); + + pldm_pdr_record *record = make_new_record( + repo, data, size, record_handle, is_remote, terminus_handle); + add_record_after_record_handle(repo, record, prev_record_handle); + + return record->record_handle; +} + pldm_pdr *pldm_pdr_init() { pldm_pdr *repo = malloc(sizeof(pldm_pdr)); @@ -169,6 +276,24 @@ const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo, return NULL; } +bool pldm_pdr_find_prev_record_handle(pldm_pdr *repo, uint32_t record_handle, + uint32_t *prev_record_handle) +{ + + assert(repo != NULL); + pldm_pdr_record *curr = repo->first; + pldm_pdr_record *prev = repo->first; + while (curr != NULL) { + if (curr->record_handle == record_handle) { + *prev_record_handle = prev->record_handle; + return true; + } + prev = curr; + curr = curr->next; + } + return false; +} + const pldm_pdr_record * pldm_pdr_get_next_record(const pldm_pdr *repo, const pldm_pdr_record *curr_record, uint8_t **data, @@ -256,7 +381,7 @@ uint32_t pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle, uint16_t fru_rsi, uint16_t entity_type, uint16_t entity_instance_num, uint16_t container_id, - uint32_t bmc_record_handle) + uint32_t bmc_record_handle, bool hotplug) { uint32_t size = sizeof(struct pldm_pdr_hdr) + sizeof(struct pldm_pdr_fru_record_set); @@ -274,17 +399,25 @@ uint32_t pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle, fru->terminus_handle = htole16(terminus_handle); fru->fru_rsi = htole16(fru_rsi); fru->entity_type = htole16(entity_type); - fru->entity_instance_num = htole16(entity_instance_num); + fru->entity_instance = htole16(entity_instance_num); fru->container_id = htole16(container_id); - return pldm_pdr_add(repo, data, size, bmc_record_handle, false, - terminus_handle); + uint32_t prev_record_handle = bmc_record_handle - 1; + if (hotplug) { + return pldm_pdr_add_hotplug_record( + repo, data, size, bmc_record_handle, false, + prev_record_handle, fru->terminus_handle); + + } else { + return pldm_pdr_add(repo, data, size, bmc_record_handle, false, + fru->terminus_handle); + } } const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle, uint16_t *entity_type, uint16_t *entity_instance_num, - uint16_t *container_id) + uint16_t *container_id, bool is_remote) { assert(terminus_handle != NULL); assert(entity_type != NULL); @@ -299,11 +432,11 @@ const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( struct pldm_pdr_fru_record_set *fru = (struct pldm_pdr_fru_record_set *)(data + sizeof(struct pldm_pdr_hdr)); - if (fru->fru_rsi == htole16(fru_rsi)) { + if (fru->fru_rsi == htole16(fru_rsi) && + curr_record->is_remote == is_remote) { *terminus_handle = le16toh(fru->terminus_handle); *entity_type = le16toh(fru->entity_type); - *entity_instance_num = - le16toh(fru->entity_instance_num); + *entity_instance_num = le16toh(fru->entity_instance); *container_id = le16toh(fru->container_id); return curr_record; } @@ -320,6 +453,54 @@ const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi( return NULL; } +uint32_t pldm_pdr_remove_fru_record_set_by_rsi(pldm_pdr *repo, uint16_t fru_rsi, + bool is_remote) +{ + assert(repo != NULL); + + uint32_t delete_hdl = 0; + pldm_pdr_record *record = repo->first; + pldm_pdr_record *prev = NULL; + while (record != NULL) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if ((record->is_remote == is_remote) && + hdr->type == PLDM_PDR_FRU_RECORD_SET) { + struct pldm_pdr_fru_record_set *fru = + (struct pldm_pdr_fru_record_set + *)((uint8_t *)record->data + + sizeof(struct pldm_pdr_hdr)); + if (fru->fru_rsi == fru_rsi) { + delete_hdl = hdr->record_handle; + if (repo->first == record) { + repo->first = next; + } else { + prev->next = next; + } + if (repo->last == record) { + repo->last = prev; + if (prev != NULL) { + prev->next = NULL; // sm00 + } + } + --repo->record_count; + repo->size -= record->size; + if (record->data) { + free(record->data); + } + free(record); + break; + } else { + prev = record; + } + } else { + prev = record; + } + record = next; + } + return delete_hdl; +} + void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminusHandle, uint8_t tid, uint8_t tlEid, bool validBit) { @@ -347,6 +528,295 @@ void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminusHandle, } while (record); } +void pldm_delete_by_record_handle(pldm_pdr *repo, uint32_t record_handle, + bool is_remote) +{ + assert(repo != NULL); + + pldm_pdr_record *record = repo->first; + pldm_pdr_record *prev = NULL; + while (record != NULL) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if ((record->is_remote == is_remote) && + (hdr->record_handle == record_handle)) { + if (repo->first == record) { + repo->first = next; + } else { + prev->next = next; + } + if (repo->last == record) { + repo->last = prev; + } + if (record->data) { + free(record->data); + } + --repo->record_count; + repo->size -= record->size; + free(record); + break; + } else { + prev = record; + } + record = next; + } +} + +pldm_entity pldm_get_entity_from_record_handle(const pldm_pdr *repo, + uint32_t record_handle) +{ + assert(repo != NULL); + pldm_entity element = {0, 0, 0}; + + pldm_pdr_record *record = repo->first; + + while (record != NULL) { + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (hdr->record_handle == record_handle) { + switch (hdr->type) { + case (PLDM_PDR_FRU_RECORD_SET): { + struct pldm_pdr_fru_record_set *pdr = + (struct pldm_pdr_fru_record_set + *)((uint8_t *)record->data + + sizeof(struct pldm_pdr_hdr)); + element.entity_type = pdr->entity_type; + element.entity_instance_num = + pdr->entity_instance; + element.entity_container_id = pdr->container_id; + return element; + } + case (PLDM_STATE_SENSOR_PDR): { + struct pldm_state_sensor_pdr *pdr = + (struct pldm_state_sensor_pdr + *)((uint8_t *)record->data); + element.entity_type = pdr->entity_type; + element.entity_instance_num = + pdr->entity_instance; + element.entity_container_id = pdr->container_id; + return element; + } + case (PLDM_STATE_EFFECTER_PDR): { + struct pldm_state_effecter_pdr *pdr = + (struct pldm_state_effecter_pdr + *)((uint8_t *)record->data); + element.entity_type = pdr->entity_type; + element.entity_instance_num = + pdr->entity_instance; + element.entity_container_id = pdr->container_id; + return element; + } + case (PLDM_NUMERIC_EFFECTER_PDR): { + struct pldm_numeric_effecter_value_pdr *pdr = + (struct pldm_numeric_effecter_value_pdr + *)((uint8_t *)record->data); + element.entity_type = pdr->entity_type; + element.entity_instance_num = + pdr->entity_instance; + element.entity_container_id = pdr->container_id; + return element; + } + default: + break; + } + } + record = record->next; + } + return element; +} + +void pldm_change_container_id_of_effecter(const pldm_pdr *repo, + uint16_t effecterId, + uint16_t containerId) +{ + assert(repo != NULL); + + pldm_pdr_record *record = repo->first; + + while (record != NULL) { + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (hdr->type == PLDM_NUMERIC_EFFECTER_PDR) { + struct pldm_numeric_effecter_value_pdr *pdr = + (struct pldm_numeric_effecter_value_pdr + *)((uint8_t *)record->data); + if (pdr->effecter_id == effecterId) { + pdr->container_id = containerId; + break; + } + } else if (hdr->type == PLDM_STATE_EFFECTER_PDR) { + struct pldm_state_effecter_pdr *pdr = + (struct pldm_state_effecter_pdr *)((uint8_t *)record + ->data); + if (pdr->effecter_id == effecterId) { + pdr->container_id = containerId; + break; + } + } + record = record->next; + } +} + +void pldm_change_container_id_of_sensor(const pldm_pdr *repo, uint16_t sensorId, + uint16_t containerId) +{ + assert(repo != NULL); + + pldm_pdr_record *record = repo->first; + + while (record != NULL) { + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (hdr->type == PLDM_STATE_SENSOR_PDR) { + struct pldm_state_sensor_pdr *pdr = + (struct pldm_state_sensor_pdr *)((uint8_t *) + record->data); + if (pdr->sensor_id == sensorId) { + pdr->container_id = containerId; + break; + } + } + record = record->next; + } +} + +void pldm_change_instance_number_of_effecter(const pldm_pdr *repo, + uint16_t effecterId, + uint16_t instanceNumber) +{ + assert(repo != NULL); + + pldm_pdr_record *record = repo->first; + + while (record != NULL) { + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (hdr->type == PLDM_STATE_EFFECTER_PDR) { + struct pldm_state_effecter_pdr *pdr = + (struct pldm_state_effecter_pdr *)((uint8_t *)record + ->data); + if (pdr->effecter_id == effecterId) { + pdr->entity_instance = instanceNumber; + break; + } + } + record = record->next; + } +} + +void pldm_change_instance_number_of_sensor(const pldm_pdr *repo, + uint16_t sensorId, + uint16_t instanceNumber) +{ + assert(repo != NULL); + + pldm_pdr_record *record = repo->first; + + while (record != NULL) { + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (hdr->type == PLDM_STATE_SENSOR_PDR) { + struct pldm_state_sensor_pdr *pdr = + (struct pldm_state_sensor_pdr *)((uint8_t *) + record->data); + if (pdr->sensor_id == sensorId) { + pdr->entity_instance = instanceNumber; + break; + } + } + record = record->next; + } +} + +uint16_t pldm_delete_by_effecter_id(pldm_pdr *repo, uint16_t effecter_id, + bool is_remote) +{ + assert(repo != NULL); + + uint32_t delete_handle = 0; + pldm_pdr_record *record = repo->first; + pldm_pdr_record *prev = NULL; + while (record != NULL) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if ((record->is_remote == is_remote) && + hdr->type == PLDM_STATE_EFFECTER_PDR) { + struct pldm_state_effecter_pdr *pdr = + (struct pldm_state_effecter_pdr *)((uint8_t *)record + ->data); + if (pdr->effecter_id == effecter_id) { + delete_handle = hdr->record_handle; + if (repo->first == record) { + repo->first = next; + } else { + prev->next = next; + } + if (repo->last == record) { + repo->last = prev; + if (prev != NULL) { + prev->next = NULL; + } + } + --repo->record_count; + repo->size -= record->size; + if (record->data) { + free(record->data); + } + free(record); + break; + } else { + prev = record; + } + } else { + prev = record; + } + record = next; + } + return delete_handle; +} + +uint16_t pldm_delete_by_sensor_id(pldm_pdr *repo, uint16_t sensor_id, + bool is_remote) +{ + assert(repo != NULL); + + uint32_t delete_handle = 0; + pldm_pdr_record *record = repo->first; + pldm_pdr_record *prev = NULL; + while (record != NULL) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if ((record->is_remote == is_remote) && + hdr->type == PLDM_STATE_SENSOR_PDR) { + struct pldm_state_sensor_pdr *pdr = + (struct pldm_state_sensor_pdr *)((uint8_t *) + record->data); + if (pdr->sensor_id == sensor_id) { + delete_handle = hdr->record_handle; + if (repo->first == record) { + repo->first = next; + } else { + prev->next = next; + } + if (repo->last == record) { + repo->last = prev; + if (prev != NULL) { + prev->next = NULL; + } + } + --repo->record_count; + repo->size -= record->size; + if (record->data) { + free(record->data); + } + free(record); + break; + } else { + prev = record; + } + } else { + prev = record; + } + record = next; + } + return delete_handle; +} + typedef struct pldm_entity_association_tree { pldm_entity_node *root; uint16_t last_used_container_id; @@ -355,12 +825,13 @@ typedef struct pldm_entity_association_tree { typedef struct pldm_entity_node { pldm_entity entity; pldm_entity parent; + uint16_t host_container_id; pldm_entity_node *first_child; pldm_entity_node *next_sibling; uint8_t association_type; } pldm_entity_node; -static inline uint16_t next_container_id(pldm_entity_association_tree *tree) +uint16_t next_container_id(pldm_entity_association_tree *tree) { assert(tree != NULL); assert(tree->last_used_container_id != UINT16_MAX); @@ -370,9 +841,19 @@ static inline uint16_t next_container_id(pldm_entity_association_tree *tree) pldm_entity pldm_entity_extract(pldm_entity_node *node) { - assert(node != NULL); + if (node != NULL) { + return node->entity; + } - return node->entity; + pldm_entity entity = {0, 0, 0}; + return entity; +} + +uint16_t pldm_extract_host_container_id(const pldm_entity_node *entity) +{ + assert(entity != NULL); + + return entity->host_container_id; } pldm_entity_association_tree *pldm_entity_association_tree_init() @@ -386,9 +867,12 @@ pldm_entity_association_tree *pldm_entity_association_tree_init() return tree; } -static pldm_entity_node *find_insertion_at(pldm_entity_node *start, - uint16_t entity_type) +static pldm_entity_node * +find_insertion_at(pldm_entity_node *start, + uint16_t entity_type) //,uint16_t *instance) //sm00 { + /*printf("\nenter find_insertion_at start->entity.entity_type=%d and + entity_type=%d", start->entity.entity_type,entity_type); */ assert(start != NULL); /* Insert after the the last node that matches the input entity type, or @@ -403,17 +887,37 @@ static pldm_entity_node *find_insertion_at(pldm_entity_node *start, } start = start->next_sibling; } - + /*while (start->next_sibling != NULL) //sm00 + { + uint16_t this_type = start->entity.entity_type; + if (this_type == entity_type) + { + *instance = start->entity.entity_instance_num; + } + start = start->next_sibling; + }*/ + // printf("\nfrom find_insertion_at returning instance=%d",*instance); return start; } pldm_entity_node *pldm_entity_association_tree_add( pldm_entity_association_tree *tree, pldm_entity *entity, uint16_t entity_instance_number, pldm_entity_node *parent, - uint8_t association_type) + uint8_t association_type, bool is_remote, bool is_update_contanier_id, + uint16_t container_id) { + /*printf("\nenter pldm_entity_association_tree_add"); */ + if (parent) { + /* printf("\nenter pldm_entity_association_tree_add with + * parent entity_type=%d, + * entity_instance_num=%d,ntity_container_id=%d", + * parent->entity.entity_type, + * parent->entity.entity_instance_num, + * parent->entity.entity_container_id);*/ + } assert(tree != NULL); assert(entity != NULL); + // uint16_t instance = 0; //sm00 if (entity_instance_number != 0xFFFF && parent != NULL) { pldm_entity node; @@ -437,21 +941,56 @@ pldm_entity_node *pldm_entity_association_tree_add( node->entity.entity_instance_num = entity_instance_number != 0xFFFF ? entity_instance_number : 1; node->association_type = association_type; + node->host_container_id = 0; if (tree->root == NULL) { assert(parent == NULL); tree->root = node; /* container_id 0 here indicates this is the top-most entry */ node->entity.entity_container_id = 0; + node->host_container_id = node->entity.entity_container_id; } else if (parent != NULL && parent->first_child == NULL) { parent->first_child = node; node->parent = parent->entity; - node->entity.entity_container_id = next_container_id(tree); + if (is_remote) { + node->host_container_id = entity->entity_container_id; + if (is_update_contanier_id) { + if (container_id != 0xFFFF) { + node->entity.entity_container_id = + container_id; + } else { + node->entity.entity_container_id = + next_container_id(tree); + } + } else { + node->entity.entity_container_id = + entity->entity_container_id; + } + } else { + if (is_update_contanier_id) { + if (container_id != 0xFFFF) { + node->entity.entity_container_id = + container_id; + } else { + node->entity.entity_container_id = + next_container_id(tree); + } + } else { + node->entity.entity_container_id = + entity->entity_container_id; + } + node->host_container_id = + node->entity.entity_container_id; + } } else { + /* printf("\ncreating the node now\n"); */ pldm_entity_node *start = parent == NULL ? tree->root : parent->first_child; pldm_entity_node *prev = - find_insertion_at(start, entity->entity_type); + find_insertion_at(start, entity->entity_type); // sm00 + // find_insertion_at(start, entity->entity_type,&instance); + // printf("\nreturned from find_insertion_at with + // instance=%d",instance); assert(prev != NULL); pldm_entity_node *next = prev->next_sibling; if (prev->entity.entity_type == entity->entity_type) { @@ -461,15 +1000,24 @@ pldm_entity_node *pldm_entity_association_tree_add( ? entity_instance_number : prev->entity.entity_instance_num + 1; } + /*else //sm00 + { + printf("\ncm node add \n"); + node->entity.entity_instance_num = instance + 1; + }*/ prev->next_sibling = node; node->parent = prev->parent; node->next_sibling = next; node->entity.entity_container_id = prev->entity.entity_container_id; + node->host_container_id = entity->entity_container_id; } entity->entity_instance_num = node->entity.entity_instance_num; - entity->entity_container_id = node->entity.entity_container_id; + if (is_update_contanier_id) { + entity->entity_container_id = node->entity.entity_container_id; + } + /*printf("\nexit pldm_entity_association_tree_add"); */ return node; } @@ -536,6 +1084,51 @@ void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree) free(tree); } +void pldm_entity_association_tree_delete_node( + pldm_entity_association_tree *tree, pldm_entity entity) +{ + // printf("\nenter pldm_entity_association_tree_delete_node"); + pldm_entity_node *node = NULL; + pldm_find_entity_ref_in_tree(tree, entity, &node); + assert(node != NULL); + // sm00 + /* printf( + "\nfound node to delete " + "node->entity.entity_type=%d,node->entity.entity_instance_num=%d", + node->entity.entity_type, + node->entity.entity_instance_num);*/ + pldm_entity_node *parent = NULL; + pldm_find_entity_ref_in_tree(tree, node->parent, &parent); + // printf("\nfound parent"); + assert(parent != NULL); + pldm_entity_node *start = parent->first_child; + pldm_entity_node *prev = parent->first_child; + while (start != NULL) { + pldm_entity current_entity; + current_entity.entity_type = start->entity.entity_type; + current_entity.entity_instance_num = + start->entity.entity_instance_num; + current_entity.entity_container_id = + start->entity.entity_container_id; + if (current_entity.entity_type == entity.entity_type && + current_entity.entity_instance_num == + entity.entity_instance_num && + current_entity.entity_container_id == + entity.entity_container_id) { + if (start == parent->first_child) { + parent->first_child = start->next_sibling; + } else { + prev->next_sibling = start->next_sibling; + } + start->next_sibling = NULL; + break; + } + prev = start; + start = start->next_sibling; + } + entity_association_tree_destroy(node); +} + inline bool pldm_entity_is_node_parent(pldm_entity_node *node) { assert(node != NULL); @@ -602,12 +1195,10 @@ bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node) return false; } -static void _entity_association_pdr_add_entry(pldm_entity_node *curr, - pldm_pdr *repo, uint16_t size, - uint8_t contained_count, - uint8_t association_type, - bool is_remote, - uint16_t terminus_handle) +static void _entity_association_pdr_add_entry( + pldm_entity_node *curr, pldm_pdr *repo, uint16_t size, + uint8_t contained_count, uint8_t association_type, bool is_remote, + uint16_t terminus_handle, uint32_t record_handle) { uint8_t pdr[size]; uint8_t *start = pdr; @@ -649,12 +1240,14 @@ static void _entity_association_pdr_add_entry(pldm_entity_node *curr, node = node->next_sibling; } - pldm_pdr_add(repo, pdr, size, 0, is_remote, terminus_handle); + pldm_pdr_add(repo, pdr, size, record_handle, is_remote, + terminus_handle); } static void entity_association_pdr_add_entry(pldm_entity_node *curr, pldm_pdr *repo, bool is_remote, - uint16_t terminus_handle) + uint16_t terminus_handle, + uint32_t record_handle) { uint8_t num_logical_children = pldm_entity_get_num_children(curr, PLDM_ENTITY_ASSOCIAION_LOGICAL); @@ -668,7 +1261,8 @@ static void entity_association_pdr_add_entry(pldm_entity_node *curr, (num_logical_children * sizeof(pldm_entity)); _entity_association_pdr_add_entry( curr, repo, logical_pdr_size, num_logical_children, - PLDM_ENTITY_ASSOCIAION_LOGICAL, is_remote, terminus_handle); + PLDM_ENTITY_ASSOCIAION_LOGICAL, is_remote, terminus_handle, + record_handle); } if (num_physical_children) { @@ -678,8 +1272,8 @@ static void entity_association_pdr_add_entry(pldm_entity_node *curr, (num_physical_children * sizeof(pldm_entity)); _entity_association_pdr_add_entry( curr, repo, physical_pdr_size, num_physical_children, - PLDM_ENTITY_ASSOCIAION_PHYSICAL, is_remote, - terminus_handle); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, is_remote, terminus_handle, + record_handle); } } @@ -701,7 +1295,8 @@ bool is_present(pldm_entity entity, pldm_entity **entities, size_t num_entities) static void entity_association_pdr_add(pldm_entity_node *curr, pldm_pdr *repo, pldm_entity **entities, size_t num_entities, bool is_remote, - uint16_t terminus_handle) + uint16_t terminus_handle, + uint32_t record_handle) { if (curr == NULL) { return; @@ -709,13 +1304,15 @@ static void entity_association_pdr_add(pldm_entity_node *curr, pldm_pdr *repo, bool to_add = true; to_add = is_present(curr->entity, entities, num_entities); if (to_add) { - entity_association_pdr_add_entry(curr, repo, is_remote, - terminus_handle); + entity_association_pdr_add_entry( + curr, repo, is_remote, terminus_handle, record_handle); } entity_association_pdr_add(curr->next_sibling, repo, entities, - num_entities, is_remote, terminus_handle); + num_entities, is_remote, terminus_handle, + record_handle); entity_association_pdr_add(curr->first_child, repo, entities, - num_entities, is_remote, terminus_handle); + num_entities, is_remote, terminus_handle, + record_handle); } void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree, @@ -726,17 +1323,444 @@ void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree, assert(repo != NULL); entity_association_pdr_add(tree->root, repo, NULL, 0, is_remote, - terminus_handle); + terminus_handle, 0); } void pldm_entity_association_pdr_add_from_node( pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities, - size_t num_entities, bool is_remote, uint16_t terminus_handle) + size_t num_entities, bool is_remote, uint16_t terminus_handle, + uint32_t record_handle) { assert(repo != NULL); entity_association_pdr_add(node, repo, entities, num_entities, - is_remote, terminus_handle); + is_remote, terminus_handle, record_handle); +} + +uint32_t find_record_handle_by_contained_entity(pldm_pdr *repo, + pldm_entity entity, + bool is_remote) +{ + /*printf("\nenter find_record_handle_by_contained_entity with " + "entity_type=%d, entity_instance_num=%d, " + "entity_container_id=%d,is_remote=%d", + entity.entity_type, entity.entity_instance_num, + entity.entity_container_id, is_remote);*/ + uint32_t record_handle = 0; + bool found = false; + assert(repo != NULL); + pldm_pdr_record *record = repo->first; + while (record != NULL && !found) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if ((record->is_remote == is_remote) && + hdr->type == PLDM_PDR_ENTITY_ASSOCIATION) { + /* printf("\ngot one PLDM_PDR_ENTITY_ASSOCIATION " + "record_handle=%d", + record->record_handle);*/ + struct pldm_pdr_entity_association *pdr = + (struct pldm_pdr_entity_association + *)((uint8_t *)record->data + + sizeof(struct pldm_pdr_hdr)); + /* printf("\npdr->container_id=%d,pdr->num_children=%d", + pdr->container_id, pdr->num_children);*/ + struct pldm_entity *child = + (struct pldm_entity *)(&pdr->children[0]); + for (int i = 0; i < pdr->num_children; ++i) { + if (child->entity_type == entity.entity_type && + child->entity_instance_num == + entity.entity_instance_num && + child->entity_container_id == + entity.entity_container_id) { + /* printf("\nFOUND + record_handle=%d", + record->record_handle);*/ + found = true; + record_handle = record->record_handle; + break; + } + child++; + } + } // end if PLDM_PDR_ENTITY_ASSOCIATION + // record = record->next; + record = next; + } // end while + return record_handle; +} + +uint32_t pldm_entity_association_pdr_remove_contained_entity( + pldm_pdr *repo, pldm_entity entity, uint8_t *event_data_op, bool is_remote) +{ + assert(repo != NULL); + uint32_t updated_hdl = 0; + bool removed = false; + *event_data_op = PLDM_RECORDS_MODIFIED; + updated_hdl = + find_record_handle_by_contained_entity(repo, entity, is_remote); + if (!updated_hdl || !entity.entity_type) { + *event_data_op = PLDM_INVALID_OP; + return updated_hdl; + } + + /* printf("\npldm_entity_association_pdr_remove_contained_entity + found " "the record handle to delete %d", updated_hdl);*/ + + pldm_pdr_record *record = repo->first; + pldm_pdr_record *prev = repo->first; + pldm_pdr_record *new_record = malloc(sizeof(pldm_pdr_record)); + new_record->data = NULL; // sm00 + // new_record->data = malloc(record->size - sizeof(pldm_entity)); //sm00 + // new_record->next = NULL; //sm00 + // uint8_t *new_data = new_record->data; //sm00 + while (record != NULL) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if (record->record_handle == + updated_hdl) /*(record->is_remote == is_remote) &&*/ + /*hdr->type == PLDM_PDR_ENTITY_ASSOCIATION)*/ { + new_record->data = + malloc(record->size - sizeof(pldm_entity)); // sm00 + new_record->next = NULL; // sm00 + new_record->record_handle = + htole32(record->record_handle); + new_record->size = + htole32(record->size - sizeof(pldm_entity)); // sm00 + new_record->is_remote = record->is_remote; + uint8_t *new_start = new_record->data; // sm00 new_data; + struct pldm_pdr_hdr *new_hdr = + (struct pldm_pdr_hdr *) + new_record->data; // sm00 new_data; + new_hdr->version = hdr->version; + new_hdr->record_handle = htole32(hdr->record_handle); + new_hdr->type = PLDM_PDR_ENTITY_ASSOCIATION; + new_hdr->record_change_num = + htole16(hdr->record_change_num); + /*new_hdr->length = + htole16(record->size - sizeof(struct pldm_pdr_hdr) - + sizeof(pldm_entity));*/ + new_hdr->length = + htole16(hdr->length - sizeof(pldm_entity)); // sm00 + new_start += sizeof(struct pldm_pdr_hdr); + struct pldm_pdr_entity_association *new_pdr = + (struct pldm_pdr_entity_association *)new_start; + + struct pldm_pdr_entity_association *pdr = + (struct pldm_pdr_entity_association + *)((uint8_t *)record->data + + sizeof(struct pldm_pdr_hdr)); + struct pldm_entity *child = + (struct pldm_entity *)(&pdr->children[0]); + + new_pdr->container_id = pdr->container_id; + new_pdr->association_type = pdr->association_type; + new_pdr->container.entity_type = + pdr->container.entity_type; + new_pdr->container.entity_instance_num = + pdr->container.entity_instance_num; + new_pdr->container.entity_container_id = + pdr->container.entity_container_id; + new_pdr->num_children = + pdr->num_children - + 1; // if this becomes 0 then just delete. no new + // entity assoc pdr is needed PENDING. can test + // once pcie cards are placed under slots + struct pldm_entity *new_child = + (struct pldm_entity *)(&new_pdr->children[0]); + + for (int i = 0; i < pdr->num_children; ++i) { + if (child->entity_type == entity.entity_type && + child->entity_instance_num == + entity.entity_instance_num && + child->entity_container_id == + entity.entity_container_id) { + removed = true; + // updated_hdl = + // hdr->record_handle; sm00 not needed + // as we are getting earlier + // skip this child.do not add in the + // new pdr + } else { + new_child->entity_type = + child->entity_type; + new_child->entity_instance_num = + child->entity_instance_num; + new_child->entity_container_id = + child->entity_container_id; + new_child++; + } + + ++child; + } + if (!new_pdr + ->num_children) // record will be deleted and + // new_record will not be added + { + removed = false; + *event_data_op = PLDM_RECORDS_DELETED; + if (repo->first == record) { + repo->first = record->next; + record->next = NULL; + } else if (repo->last == record) { + repo->last = prev; + prev->next = NULL; + } else { + prev->next = record->next; + record->next = NULL; + } + repo->size -= record->size; + repo->record_count--; + if (record->data) { + free(record->data); + } + free(record); + break; + } else if (removed) { + if (repo->first == record) { + repo->first = new_record; + new_record->next = record->next; + } else { + prev->next = new_record; + new_record->next = record->next; + record->next = NULL; // sm00 + } + if (repo->last == record) { + repo->last = new_record; + new_record->next = NULL; // sm00 + } + repo->size -= record->size; + repo->size += new_record->size; + + if (record->data) { + free(record->data); + } + free(record); + break; + } + } + prev = record; + record = next; + } + if (!removed) { + if (new_record->data) // sm00 + { + free(new_record->data); // sm00 + } + if (new_record) { + free(new_record); + } + // free(new_data); sm00 + } + return updated_hdl; +} + +uint32_t pldm_entity_association_pdr_add_contained_entity( + pldm_pdr *repo, pldm_entity entity, pldm_entity parent, + uint8_t *event_data_op, bool is_remote, uint32_t bmc_record_handle) +{ + /*printf("\nenter pldm_entity_association_pdr_add_contained_entity + entity type=%d entity ins=%d container id=%d", entity.entity_type, + entity.entity_instance_num, entity.entity_container_id); printf("\n and + parent entity type=%d entity ins=%d container id=%d",parent.entity_type, + parent.entity_instance_num, parent.entity_container_id);*/ + // testing pending with pcie slot-card. can test once cards are placed + // under slots in DBus. usecase: will not find the PDR and need to + // create a new entity assoc PDR since the number of child is always 1 + // if the PDR is not found then search for the PDR having parent as a + // child if found then parent is valid and create a new enitity assoc + // PDR with parent-entity + uint32_t updated_hdl = 0; + bool added = false; + *event_data_op = PLDM_RECORDS_MODIFIED; + pldm_pdr_record *record = repo->first; + pldm_pdr_record *prev = repo->first; + pldm_pdr_record *new_record = malloc(sizeof(pldm_pdr_record)); + new_record->data = NULL; // sm00 + // new_record->data = malloc(record->size + sizeof(pldm_entity)); //sm00 + // new_record->next = NULL; //sm00 + uint8_t *new_data = NULL; // new_record->data; //sm00 + bool found = false; + while (record != NULL) { + pldm_pdr_record *next = record->next; + struct pldm_pdr_hdr *hdr = (struct pldm_pdr_hdr *)record->data; + if ((record->is_remote == is_remote) && + hdr->type == PLDM_PDR_ENTITY_ASSOCIATION) { + struct pldm_pdr_entity_association *pdr = + (struct pldm_pdr_entity_association + *)((uint8_t *)record->data + + sizeof(struct pldm_pdr_hdr)); + if (pdr->container.entity_type == parent.entity_type && + pdr->container.entity_instance_num == + parent.entity_instance_num && + pdr->container.entity_container_id == + parent.entity_container_id) { + found = true; + new_record->data = malloc( + record->size + sizeof(pldm_entity)); // sm00 + new_record->next = NULL; // sm00 + new_data = new_record->data; // sm00 + updated_hdl = record->record_handle; + new_record->record_handle = + htole32(record->record_handle); + new_record->size = + htole32(record->size + sizeof(pldm_entity)); + new_record->is_remote = record->is_remote; + uint8_t *new_start = new_data; + struct pldm_pdr_hdr *new_hdr = + (struct pldm_pdr_hdr *)new_data; + new_hdr->version = hdr->version; + new_hdr->record_handle = + htole32(hdr->record_handle); + new_hdr->type = PLDM_PDR_ENTITY_ASSOCIATION; + new_hdr->record_change_num = + htole16(hdr->record_change_num); + /* new_hdr->length = htole16( + record->size - sizeof(struct + pldm_pdr_hdr) + sizeof(pldm_entity)); */ + new_hdr->length = htole16( + hdr->length + sizeof(pldm_entity)); // sm00 + new_start += sizeof(struct pldm_pdr_hdr); + struct pldm_pdr_entity_association *new_pdr = + (struct pldm_pdr_entity_association *) + new_start; + + struct pldm_entity *child = + (struct pldm_entity *)(&pdr->children[0]); + + new_pdr->container_id = pdr->container_id; + new_pdr->association_type = + pdr->association_type; + new_pdr->container.entity_type = + pdr->container.entity_type; + new_pdr->container.entity_instance_num = + pdr->container.entity_instance_num; + new_pdr->container.entity_container_id = + pdr->container.entity_container_id; + new_pdr->num_children = pdr->num_children + 1; + struct pldm_entity *new_child = + (struct pldm_entity *)(&new_pdr + ->children[0]); + for (int i = 0; i < pdr->num_children; ++i) { + new_child->entity_type = + child->entity_type; + new_child->entity_instance_num = + child->entity_instance_num; + new_child->entity_container_id = + child->entity_container_id; + new_child++; + child++; + } + new_child->entity_type = entity.entity_type; + new_child->entity_instance_num = + entity.entity_instance_num; + new_child->entity_container_id = + entity.entity_container_id; + + added = true; + if (repo->first == record) { + repo->first = new_record; + new_record->next = record->next; + } else { + prev->next = new_record; + new_record->next = record->next; + } + if (repo->last == record) { + repo->last = new_record; + } + repo->size -= record->size; + repo->size += new_record->size; + + if (record->data) { + free(record->data); + } + free(record); + break; + } + } + + prev = record; + record = next; + } + if (!found && !is_remote) // need to create a new entity assoc pdr + { + // printf("\ncreating a new entity assoc pdr for slot \n"); + uint8_t num_children = 1; + added = false; + *event_data_op = PLDM_RECORDS_ADDED; + prev = repo->first; + pldm_pdr_record *curr = repo->first; + while (curr != NULL) { + if (curr->record_handle == bmc_record_handle) { + // printf("\nfound the place \n"); + added = true; + break; + } + prev = curr; + curr = curr->next; + } + + if (added) { + uint16_t new_pdr_size = + sizeof(struct pldm_pdr_hdr) + sizeof(uint16_t) + + sizeof(uint8_t) + sizeof(pldm_entity) + + sizeof(uint8_t) + + num_children * sizeof(pldm_entity); + new_record->data = malloc(new_pdr_size); + new_record->record_handle = bmc_record_handle + 1; + new_record->size = new_pdr_size; + new_record->is_remote = false; + new_record->next = curr->next; + curr->next = new_record; + if (repo->last == prev) { + repo->last = new_record; + } + repo->size += new_record->size; + ++repo->record_count; + + updated_hdl = new_record->record_handle; + + struct pldm_pdr_hdr *new_hdr = + (struct pldm_pdr_hdr *)new_record->data; + new_hdr->version = 1; + new_hdr->record_handle = new_record->record_handle; + new_hdr->type = PLDM_PDR_ENTITY_ASSOCIATION; + new_hdr->record_change_num = 0; + new_hdr->length = + htole16(new_pdr_size - sizeof(struct pldm_pdr_hdr)); + + struct pldm_pdr_entity_association *new_pdr = + (struct pldm_pdr_entity_association + *)((uint8_t *)new_record->data + + sizeof(struct pldm_pdr_hdr)); + new_pdr->container.entity_type = parent.entity_type; + new_pdr->container.entity_instance_num = + parent.entity_instance_num; + new_pdr->container.entity_container_id = + parent.entity_container_id; + new_pdr->container_id = entity.entity_container_id; + new_pdr->association_type = + PLDM_ENTITY_ASSOCIAION_PHYSICAL; + new_pdr->num_children = 1; + struct pldm_entity *new_child = + (struct pldm_entity *)(&new_pdr->children[0]); + new_child->entity_type = entity.entity_type; + new_child->entity_instance_num = + entity.entity_instance_num; + new_child->entity_container_id = + entity.entity_container_id; + } + } + if (!added) { + if (new_record->data) // sm00 + { + free(new_record->data); // sm00 + } + if (new_record) // sm00 + { + free(new_record); // sm00 + } + } + // printf("\nreturning updated_hdl=%d", updated_hdl); + return updated_hdl; } void find_entity_ref_in_tree(pldm_entity_node *tree_node, pldm_entity entity, @@ -748,7 +1772,10 @@ void find_entity_ref_in_tree(pldm_entity_node *tree_node, pldm_entity entity, if (tree_node->entity.entity_type == entity.entity_type && tree_node->entity.entity_instance_num == - entity.entity_instance_num) { + entity.entity_instance_num && + tree_node->entity.entity_container_id == + entity.entity_container_id) { + *node = tree_node; return; } @@ -768,8 +1795,6 @@ void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo, uint16_t terminus_handle) { assert(repo != NULL); - bool removed = false; - pldm_pdr_record *record = repo->first; pldm_pdr_record *prev = NULL; while (record != NULL) { @@ -789,28 +1814,13 @@ void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo, --repo->record_count; repo->size -= record->size; free(record); - removed = true; } else { prev = record; } record = next; } - - if (removed == true) { - record = repo->first; - uint32_t record_handle = 0; - while (record != NULL) { - record->record_handle = ++record_handle; - if (record->data != NULL) { - struct pldm_pdr_hdr *hdr = - (struct pldm_pdr_hdr *)(record->data); - hdr->record_handle = - htole32(record->record_handle); - } - record = record->next; - } - } } + void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo) { assert(repo != NULL); @@ -859,31 +1869,47 @@ void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo) } void entity_association_tree_find(pldm_entity_node *node, pldm_entity *entity, - pldm_entity_node **out) + pldm_entity_node **out, bool is_remote) { if (node == NULL) { return; } + if (is_remote) { - if (node->entity.entity_type == entity->entity_type && - node->entity.entity_instance_num == entity->entity_instance_num) { - entity->entity_container_id = node->entity.entity_container_id; - *out = node; - return; + if (node->entity.entity_type == entity->entity_type && + node->entity.entity_instance_num == + entity->entity_instance_num && + node->host_container_id == entity->entity_container_id) { + entity->entity_container_id = + node->entity.entity_container_id; + + *out = node; + return; + } + } else { + if (node->entity.entity_type == entity->entity_type && + node->entity.entity_instance_num == + entity->entity_instance_num) { + entity->entity_container_id = + node->entity.entity_container_id; + *out = node; + return; + } } - entity_association_tree_find(node->next_sibling, entity, out); - entity_association_tree_find(node->first_child, entity, out); + entity_association_tree_find(node->next_sibling, entity, out, + is_remote); + entity_association_tree_find(node->first_child, entity, out, is_remote); } pldm_entity_node * pldm_entity_association_tree_find(pldm_entity_association_tree *tree, - pldm_entity *entity) + pldm_entity *entity, bool is_remote) { assert(tree != NULL); pldm_entity_node *node = NULL; - entity_association_tree_find(tree->root, entity, &node); + entity_association_tree_find(tree->root, entity, &node, is_remote); return node; } @@ -897,6 +1923,7 @@ static void entity_association_tree_copy(pldm_entity_node *org_node, (*new_node)->parent = org_node->parent; (*new_node)->entity = org_node->entity; (*new_node)->association_type = org_node->association_type; + (*new_node)->host_container_id = org_node->host_container_id; (*new_node)->first_child = NULL; (*new_node)->next_sibling = NULL; entity_association_tree_copy(org_node->first_child, @@ -970,3 +1997,20 @@ void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len, ++i; } } + +pldm_entity_node *init_pldm_entity_node(pldm_entity entity, pldm_entity parent, + uint16_t host_container_id, + pldm_entity_node *first_child, + pldm_entity_node *next_sibling, + uint8_t association_type) +{ + pldm_entity_node *node = malloc(sizeof(pldm_entity_node)); + node->entity = entity; + node->parent = parent; + node->host_container_id = host_container_id; + node->first_child = first_child; + node->next_sibling = next_sibling; + node->association_type = association_type; + + return node; +} diff --git a/tests/libpldm_pdr_test.cpp b/tests/libpldm_pdr_test.cpp index 8c572fcdc..8cacee425 100644 --- a/tests/libpldm_pdr_test.cpp +++ b/tests/libpldm_pdr_test.cpp @@ -269,7 +269,8 @@ TEST(PDRAccess, testGet) EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in)); EXPECT_EQ(nextRecHdl, 0u); - EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0); + EXPECT_EQ(memcmp(outData + 4, in.data() + 1, sizeof(in) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; auto hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl); @@ -277,7 +278,8 @@ TEST(PDRAccess, testGet) EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in)); EXPECT_EQ(nextRecHdl, 0u); - EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0); + EXPECT_EQ(memcmp(outData + 4, in.data() + 1, sizeof(in) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl2->record_handle); outData = nullptr; hdl = pldm_pdr_find_record(repo, htole32(0xdeaddead), &outData, &size, @@ -299,37 +301,47 @@ TEST(PDRAccess, testGet) EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u); EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4); hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl); + EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in)); EXPECT_EQ(nextRecHdl, 2u); - EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0); + EXPECT_EQ(memcmp(outData + 4, in.data() + 1, sizeof(in) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; + hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl); EXPECT_EQ(hdl, hdl2); EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in)); EXPECT_EQ(nextRecHdl, 2u); - EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0); + EXPECT_EQ(memcmp(outData + 4, in.data() + 1, sizeof(in) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl2->record_handle); outData = nullptr; + hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl); EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in2)); EXPECT_EQ(nextRecHdl, 3u); - EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0); + EXPECT_EQ(memcmp(outData + 4, in2.data() + 1, sizeof(in2) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; + hdl = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl); EXPECT_NE(hdl, nullptr); EXPECT_EQ(pldm_pdr_record_is_remote(hdl), false); EXPECT_EQ(size, sizeof(in2)); EXPECT_EQ(nextRecHdl, 4u); - EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0); + EXPECT_EQ(memcmp(outData + 4, in2.data() + 1, sizeof(in2) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; + hdl = pldm_pdr_find_record(repo, 4, &outData, &size, &nextRecHdl); EXPECT_NE(hdl, nullptr); EXPECT_EQ(pldm_pdr_record_is_remote(hdl), true); EXPECT_EQ(size, sizeof(in2)); EXPECT_EQ(nextRecHdl, 0u); - EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0); + EXPECT_EQ(memcmp(outData + 4, in2.data() + 1, sizeof(in2) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; pldm_pdr_destroy(repo); @@ -351,7 +363,8 @@ TEST(PDRAccess, testGetNext) EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in)); EXPECT_EQ(nextRecHdl, 0u); - EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0); + EXPECT_EQ(memcmp(outData + 4, in.data() + 1, sizeof(in) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; std::array in2{1000, 3450, 30, 60, 890, @@ -368,19 +381,24 @@ TEST(PDRAccess, testGetNext) EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in2)); EXPECT_EQ(nextRecHdl, 3u); - EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0); + EXPECT_EQ(memcmp(outData + 4, in2.data() + 1, sizeof(in2) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; + hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl); EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in2)); EXPECT_EQ(nextRecHdl, 4u); - EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0); + EXPECT_EQ(memcmp(outData + 4, in2.data() + 1, sizeof(in2) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; + hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl); EXPECT_NE(hdl, nullptr); EXPECT_EQ(size, sizeof(in2)); EXPECT_EQ(nextRecHdl, 0u); - EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0); + EXPECT_EQ(memcmp(outData + 4, in2.data() + 1, sizeof(in2) - 4), 0); + EXPECT_EQ(reinterpret_cast(outData)[0], hdl->record_handle); outData = nullptr; pldm_pdr_destroy(repo); @@ -439,11 +457,69 @@ TEST(PDRAccess, testFindByType) pldm_pdr_destroy(repo); } +TEST(PDRAccess, getPLDMEntityfromPDR) +{ + auto repo = pldm_pdr_init(); + + // Test FRU Record set PDR + auto handle = pldm_pdr_add_fru_record_set(repo, 1, 10, 1, 0, 100, 0, false); + auto entity = pldm_get_entity_from_record_handle(repo, handle); + EXPECT_EQ(entity.entity_type, htole16(1)); + EXPECT_EQ(entity.entity_instance_num, htole16(0)); + EXPECT_EQ(entity.entity_container_id, htole16(100)); + + // Test State Effecter PDR + std::array data{212, 1, 0, 0, 1, 11, 0, 0, 19, 0, + 1, 0, 196, 0, 64, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 1, 10, 0, 1, 6}; + handle = pldm_pdr_add(repo, data.data(), data.size(), 0, false, 1); + entity = pldm_get_entity_from_record_handle(repo, handle); + EXPECT_EQ(entity.entity_type, htole16(64)); + EXPECT_EQ(entity.entity_instance_num, htole16(1)); + EXPECT_EQ(entity.entity_container_id, htole16(2)); + + // Test State Sensor PDR + std::array data2{10, 1, 0, 0, 1, 4, 0, 0, 17, + 0, 1, 0, 199, 0, 120, 0, 4, 0, + 5, 0, 0, 0, 1, 10, 0, 1, 6}; + handle = pldm_pdr_add(repo, data2.data(), data2.size(), 0, false, 1); + entity = pldm_get_entity_from_record_handle(repo, handle); + EXPECT_EQ(entity.entity_type, htole16(120)); + EXPECT_EQ(entity.entity_instance_num, htole16(4)); + EXPECT_EQ(entity.entity_container_id, htole16(5)); + + // Test Numeric Effecter PDR + std::array data3{10, 1, 0, 0, 1, 9, 0, 0, 17, 0, 1, 0, 199, 0, + 6, 0, 3, 0, 2, 0, 0, 0, 1, 10, 0, 1, 6}; + handle = pldm_pdr_add(repo, data3.data(), data3.size(), 0, false, 1); + entity = pldm_get_entity_from_record_handle(repo, handle); + EXPECT_EQ(entity.entity_type, htole16(6)); + EXPECT_EQ(entity.entity_instance_num, htole16(3)); + EXPECT_EQ(entity.entity_container_id, htole16(2)); + + // Test Non Supported PDR types + std::array notSupportedtypes{ + 1, 2, 3, 5, 6, 7, 8, 10, 12, 13, 14, 15, 16, 17, 18, 19, 126, 127}; + for (const auto& type : notSupportedtypes) + { + std::array data4{}; + pldm_pdr_hdr* hdr = reinterpret_cast(data4.data()); + hdr->type = type; + auto handle = + pldm_pdr_add(repo, data4.data(), data4.size(), 0, false, 1); + entity = pldm_get_entity_from_record_handle(repo, handle); + EXPECT_EQ(entity.entity_type, htole16(0)); + EXPECT_EQ(entity.entity_instance_num, htole16(0)); + EXPECT_EQ(entity.entity_container_id, htole16(0)); + } + pldm_pdr_destroy(repo); +} + TEST(PDRUpdate, testAddFruRecordSet) { auto repo = pldm_pdr_init(); - auto handle = pldm_pdr_add_fru_record_set(repo, 1, 10, 1, 0, 100, 0); + auto handle = pldm_pdr_add_fru_record_set(repo, 1, 10, 1, 0, 100, 0, false); EXPECT_EQ(handle, 1u); EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u); EXPECT_EQ(pldm_pdr_get_repo_size(repo), @@ -465,11 +541,11 @@ TEST(PDRUpdate, testAddFruRecordSet) EXPECT_EQ(fru->terminus_handle, htole16(1)); EXPECT_EQ(fru->fru_rsi, htole16(10)); EXPECT_EQ(fru->entity_type, htole16(1)); - EXPECT_EQ(fru->entity_instance_num, htole16(0)); + EXPECT_EQ(fru->entity_instance, htole16(0)); EXPECT_EQ(fru->container_id, htole16(100)); outData = nullptr; - handle = pldm_pdr_add_fru_record_set(repo, 2, 11, 2, 1, 101, 0); + handle = pldm_pdr_add_fru_record_set(repo, 2, 11, 2, 1, 101, 0, false); EXPECT_EQ(handle, 2u); EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u); EXPECT_EQ(pldm_pdr_get_repo_size(repo), @@ -488,7 +564,7 @@ TEST(PDRUpdate, testAddFruRecordSet) EXPECT_EQ(fru->terminus_handle, htole16(2)); EXPECT_EQ(fru->fru_rsi, htole16(11)); EXPECT_EQ(fru->entity_type, htole16(2)); - EXPECT_EQ(fru->entity_instance_num, htole16(1)); + EXPECT_EQ(fru->entity_instance, htole16(1)); EXPECT_EQ(fru->container_id, htole16(101)); outData = nullptr; @@ -506,7 +582,7 @@ TEST(PDRUpdate, testAddFruRecordSet) EXPECT_EQ(fru->terminus_handle, htole16(1)); EXPECT_EQ(fru->fru_rsi, htole16(10)); EXPECT_EQ(fru->entity_type, htole16(1)); - EXPECT_EQ(fru->entity_instance_num, htole16(0)); + EXPECT_EQ(fru->entity_instance, htole16(0)); EXPECT_EQ(fru->container_id, htole16(100)); outData = nullptr; @@ -521,28 +597,28 @@ TEST(PDRUpdate, tesFindtFruRecordSet) uint16_t entityType{}; uint16_t entityInstanceNum{}; uint16_t containerId{}; - auto first = pldm_pdr_add_fru_record_set(repo, 1, 1, 1, 0, 100, 1); - auto second = pldm_pdr_add_fru_record_set(repo, 1, 2, 1, 1, 100, 2); - auto third = pldm_pdr_add_fru_record_set(repo, 1, 3, 1, 2, 100, 3); + auto first = pldm_pdr_add_fru_record_set(repo, 1, 1, 1, 0, 100, 1, false); + auto second = pldm_pdr_add_fru_record_set(repo, 1, 2, 1, 1, 100, 2, false); + auto third = pldm_pdr_add_fru_record_set(repo, 1, 3, 1, 2, 100, 3, false); EXPECT_EQ(first, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 1, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(second, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 2, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(third, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 3, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(terminusHdl, 1u); EXPECT_EQ(entityType, 1u); EXPECT_EQ(entityInstanceNum, 2u); EXPECT_EQ(containerId, 100u); EXPECT_EQ(nullptr, pldm_pdr_fru_record_set_find_by_rsi( repo, 4, &terminusHdl, &entityType, - &entityInstanceNum, &containerId)); + &entityInstanceNum, &containerId, false)); pldm_pdr_destroy(repo); } @@ -579,31 +655,40 @@ TEST(EntityAssociationPDR, testBuild) auto tree = pldm_entity_association_tree_init(); auto l1 = pldm_entity_association_tree_add( - tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l1, nullptr); - auto l2a = pldm_entity_association_tree_add( - tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2a = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2a, nullptr); - auto l2b = pldm_entity_association_tree_add( - tree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2b, nullptr); - auto l2c = pldm_entity_association_tree_add( - tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2c = pldm_entity_association_tree_add(tree, &entities[3], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2c, nullptr); - auto l3a = pldm_entity_association_tree_add( - tree, &entities[4], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3a = pldm_entity_association_tree_add(tree, &entities[4], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3a, nullptr); - auto l3b = pldm_entity_association_tree_add( - tree, &entities[5], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3b = pldm_entity_association_tree_add(tree, &entities[5], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3b, nullptr); - auto l3c = pldm_entity_association_tree_add( - tree, &entities[6], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3c = pldm_entity_association_tree_add(tree, &entities[6], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3b, nullptr); - auto l4a = pldm_entity_association_tree_add( - tree, &entities[7], 0xFFFF, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l4a = pldm_entity_association_tree_add(tree, &entities[7], 0xFFFF, l3a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l4a, nullptr); - auto l4b = pldm_entity_association_tree_add( - tree, &entities[8], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l4b = pldm_entity_association_tree_add(tree, &entities[8], 0xFFFF, l3b, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l4b, nullptr); EXPECT_EQ(pldm_entity_is_node_parent(l1), true); @@ -759,7 +844,8 @@ TEST(EntityAssociationPDR, testSpecialTrees) // A auto tree = pldm_entity_association_tree_init(); auto node = pldm_entity_association_tree_add( - tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); size_t num{}; pldm_entity* out = nullptr; @@ -774,13 +860,16 @@ TEST(EntityAssociationPDR, testSpecialTrees) // A-A-A tree = pldm_entity_association_tree_init(); node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0XFFFF); EXPECT_NE(node, nullptr); node = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); node = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); pldm_entity_association_tree_visit(tree, &out, &num); EXPECT_EQ(num, 3u); @@ -803,13 +892,16 @@ TEST(EntityAssociationPDR, testSpecialTrees) // A tree = pldm_entity_association_tree_init(); node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); auto node1 = pldm_entity_association_tree_add( - tree, &entities[1], 0xFFFF, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[1], 0xFFFF, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node1, nullptr); auto node2 = pldm_entity_association_tree_add( - tree, &entities[2], 0xFFFF, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[2], 0xFFFF, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node2, nullptr); pldm_entity_association_tree_visit(tree, &out, &num); EXPECT_EQ(num, 3u); @@ -830,16 +922,20 @@ TEST(EntityAssociationPDR, testSpecialTrees) // A-A tree = pldm_entity_association_tree_init(); node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node1, nullptr); node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node2, nullptr); pldm_entity_association_tree_visit(tree, &out, &num); EXPECT_EQ(num, 4u); @@ -897,43 +993,55 @@ TEST(EntityAssociationPDR, testPDR) auto tree = pldm_entity_association_tree_init(); auto l1 = pldm_entity_association_tree_add( - tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l1, nullptr); auto l1a = pldm_entity_association_tree_add( - tree, &entities[1], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[1], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l1a, nullptr); - auto l2a = pldm_entity_association_tree_add( - tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2a = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2a, nullptr); auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, l1, - PLDM_ENTITY_ASSOCIAION_LOGICAL); + PLDM_ENTITY_ASSOCIAION_LOGICAL, + false, true, 0xFFFF); EXPECT_NE(l2b, nullptr); - auto l2c = pldm_entity_association_tree_add( - tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2c = pldm_entity_association_tree_add(tree, &entities[3], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2c, nullptr); auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xFFFF, l1, - PLDM_ENTITY_ASSOCIAION_LOGICAL); + PLDM_ENTITY_ASSOCIAION_LOGICAL, + false, true, 0xFFFF); EXPECT_NE(l2d, nullptr); - auto l3a = pldm_entity_association_tree_add( - tree, &entities[5], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3a = pldm_entity_association_tree_add(tree, &entities[5], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3a, nullptr); - auto l3b = pldm_entity_association_tree_add( - tree, &entities[6], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3b = pldm_entity_association_tree_add(tree, &entities[6], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3b, nullptr); auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xFFFF, l2a, - PLDM_ENTITY_ASSOCIAION_LOGICAL); + PLDM_ENTITY_ASSOCIAION_LOGICAL, + false, true, 0xFFFF); EXPECT_NE(l3c, nullptr); auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xFFFF, l2a, - PLDM_ENTITY_ASSOCIAION_LOGICAL); + PLDM_ENTITY_ASSOCIAION_LOGICAL, + false, true, 0xFFFF); EXPECT_NE(l3d, nullptr); - auto l4a = pldm_entity_association_tree_add( - tree, &entities[9], 0xFFFF, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l4a = pldm_entity_association_tree_add(tree, &entities[9], 0xFFFF, l3a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l4a, nullptr); auto l4b = pldm_entity_association_tree_add( - tree, &entities[10], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL); + tree, &entities[10], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL, false, + true, 0xFFFF); EXPECT_NE(l4b, nullptr); EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL), @@ -1194,60 +1302,69 @@ TEST(EntityAssociationPDR, testFind) auto tree = pldm_entity_association_tree_init(); auto l1 = pldm_entity_association_tree_add( - tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l1, nullptr); - auto l2a = pldm_entity_association_tree_add( - tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2a = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2a, nullptr); - auto l2b = pldm_entity_association_tree_add( - tree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2b, nullptr); - auto l2c = pldm_entity_association_tree_add( - tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2c = pldm_entity_association_tree_add(tree, &entities[3], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2c, nullptr); - auto l3a = pldm_entity_association_tree_add( - tree, &entities[4], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3a = pldm_entity_association_tree_add(tree, &entities[4], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3a, nullptr); - auto l3b = pldm_entity_association_tree_add( - tree, &entities[5], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3b = pldm_entity_association_tree_add(tree, &entities[5], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3b, nullptr); - auto l3c = pldm_entity_association_tree_add( - tree, &entities[6], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l3c = pldm_entity_association_tree_add(tree, &entities[6], 0xFFFF, l2a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l3c, nullptr); - auto l4a = pldm_entity_association_tree_add( - tree, &entities[7], 0xFFFF, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l4a = pldm_entity_association_tree_add(tree, &entities[7], 0xFFFF, l3a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l4a, nullptr); - auto l4b = pldm_entity_association_tree_add( - tree, &entities[8], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l4b = pldm_entity_association_tree_add(tree, &entities[8], 0xFFFF, l3b, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l4b, nullptr); pldm_entity entity{}; entity.entity_type = 1; entity.entity_instance_num = 1; - auto result = pldm_entity_association_tree_find(tree, &entity); + auto result = pldm_entity_association_tree_find(tree, &entity, false); EXPECT_EQ(result, l1); EXPECT_EQ(entity.entity_container_id, 0); entity.entity_type = 2; entity.entity_instance_num = 1; - result = pldm_entity_association_tree_find(tree, &entity); + result = pldm_entity_association_tree_find(tree, &entity, false); EXPECT_EQ(result, l2a); EXPECT_EQ(entity.entity_container_id, 1); entity.entity_type = 2; entity.entity_instance_num = 2; - result = pldm_entity_association_tree_find(tree, &entity); + result = pldm_entity_association_tree_find(tree, &entity, false); EXPECT_EQ(result, l2b); EXPECT_EQ(entity.entity_container_id, 1); entity.entity_type = 3; entity.entity_instance_num = 1; - result = pldm_entity_association_tree_find(tree, &entity); + result = pldm_entity_association_tree_find(tree, &entity, false); EXPECT_EQ(result, l2c); EXPECT_EQ(entity.entity_container_id, 1); entity.entity_type = 7; entity.entity_instance_num = 1; - result = pldm_entity_association_tree_find(tree, &entity); + result = pldm_entity_association_tree_find(tree, &entity, false); EXPECT_EQ(result, l4b); EXPECT_EQ(entity.entity_container_id, 4); @@ -1264,18 +1381,21 @@ TEST(EntityAssociationPDR, testCopyTree) auto orgTree = pldm_entity_association_tree_init(); auto newTree = pldm_entity_association_tree_init(); - auto l1 = - pldm_entity_association_tree_add(orgTree, &entities[0], 0xFFFF, nullptr, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l1 = pldm_entity_association_tree_add( + orgTree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l1, nullptr); auto l2a = pldm_entity_association_tree_add( - orgTree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + orgTree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2a, nullptr); auto l2b = pldm_entity_association_tree_add( - orgTree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + orgTree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2b, nullptr); auto l2c = pldm_entity_association_tree_add( - orgTree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + orgTree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2c, nullptr); size_t orgNum{}; pldm_entity* orgOut = nullptr; @@ -1372,31 +1492,38 @@ TEST(EntityAssociationPDR, testGetChildren) auto tree = pldm_entity_association_tree_init(); auto l1 = pldm_entity_association_tree_add( - tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l1, nullptr); - auto l2a = pldm_entity_association_tree_add( - tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2a = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2a, nullptr); - auto l2b = pldm_entity_association_tree_add( - tree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2b, nullptr); - auto l2c = pldm_entity_association_tree_add( - tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + auto l2c = pldm_entity_association_tree_add(tree, &entities[3], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(l2c, nullptr); pldm_entity et1; et1.entity_type = 2; et1.entity_instance_num = 1; + et1.entity_container_id = 1; EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et1)); pldm_entity et2; et2.entity_type = 2; et2.entity_instance_num = 2; + et2.entity_container_id = 1; EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et2)); pldm_entity et3; et3.entity_type = 2; et3.entity_instance_num = 3; + et3.entity_container_id = 1; EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3)); pldm_entity_association_tree_destroy(tree); @@ -1413,6 +1540,7 @@ TEST(EntityAssociationPDR, testEntityInstanceNumber) entities[4].entity_type = 2; entities[5].entity_type = 2; entities[6].entity_type = 2; + entities[6].entity_container_id = 1; entities[7].entity_type = 3; entities[8].entity_type = 3; @@ -1425,111 +1553,215 @@ TEST(EntityAssociationPDR, testEntityInstanceNumber) uint16_t containerId{}; auto node = pldm_entity_association_tree_add( - tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL); + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_NE(node, nullptr); auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto first = pldm_pdr_add_fru_record_set( repo, 1, 1, entities[1].entity_type, entities[1].entity_instance_num, - entities[1].entity_container_id, 1); + entities[1].entity_container_id, 1, false); EXPECT_NE(l1, nullptr); EXPECT_EQ(entities[1].entity_instance_num, 63); EXPECT_EQ(first, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 1, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 2); EXPECT_EQ(entityInstanceNum, 63); auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto second = pldm_pdr_add_fru_record_set( repo, 1, 2, entities[2].entity_type, entities[2].entity_instance_num, - entities[2].entity_container_id, 2); + entities[2].entity_container_id, 2, false); EXPECT_NE(l2, nullptr); EXPECT_EQ(entities[2].entity_instance_num, 37); EXPECT_EQ(second, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 2, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 2); EXPECT_EQ(entityInstanceNum, 37); auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto third = pldm_pdr_add_fru_record_set( repo, 1, 3, entities[3].entity_type, entities[3].entity_instance_num, - entities[3].entity_container_id, 3); + entities[3].entity_container_id, 3, false); EXPECT_NE(l3, nullptr); EXPECT_EQ(entities[3].entity_instance_num, 44); EXPECT_EQ(third, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 3, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 2); EXPECT_EQ(entityInstanceNum, 44); auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto fourth = pldm_pdr_add_fru_record_set( repo, 1, 4, entities[4].entity_type, entities[4].entity_instance_num, - entities[4].entity_container_id, 4); + entities[4].entity_container_id, 4, false); EXPECT_NE(l4, nullptr); EXPECT_EQ(entities[4].entity_instance_num, 89); EXPECT_EQ(fourth, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 4, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 2); EXPECT_EQ(entityInstanceNum, 89); auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xFFFF, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto fifth = pldm_pdr_add_fru_record_set( repo, 1, 5, entities[5].entity_type, entities[5].entity_instance_num, - entities[5].entity_container_id, 5); + entities[5].entity_container_id, 5, false); EXPECT_NE(l5, nullptr); EXPECT_EQ(entities[5].entity_instance_num, 90); EXPECT_EQ(fifth, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 5, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 2); EXPECT_EQ(entityInstanceNum, 90); auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); EXPECT_EQ(l6, nullptr); auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto seventh = pldm_pdr_add_fru_record_set( repo, 1, 7, entities[7].entity_type, entities[7].entity_instance_num, - entities[7].entity_container_id, 7); + entities[7].entity_container_id, 7, false); EXPECT_NE(l7, nullptr); EXPECT_EQ(entities[7].entity_instance_num, 100); EXPECT_EQ(seventh, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 7, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 3); EXPECT_EQ(entityInstanceNum, 100); auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2, - PLDM_ENTITY_ASSOCIAION_PHYSICAL); + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); auto eighth = pldm_pdr_add_fru_record_set( repo, 1, 8, entities[8].entity_type, entities[8].entity_instance_num, - entities[8].entity_container_id, 8); + entities[8].entity_container_id, 8, false); EXPECT_NE(l8, nullptr); EXPECT_EQ(entities[8].entity_instance_num, 100); EXPECT_EQ(eighth, pldm_pdr_get_record_handle( repo, pldm_pdr_fru_record_set_find_by_rsi( repo, 8, &terminusHdl, &entityType, - &entityInstanceNum, &containerId))); + &entityInstanceNum, &containerId, false))); EXPECT_EQ(entityType, 3); EXPECT_EQ(entityInstanceNum, 100); pldm_pdr_destroy(repo); pldm_entity_association_tree_destroy(tree); } + +TEST(EntityAssociationPDR, findAndAddHostPDR) +{ + + // Tree - 1 + // + // 11521(1,0) + // | + // 45 (1,1) + // | + // 64 (1,2) + // | + // ----------------------- + // | | + // 67(0,3) 67(1,3) + // | | + // 135(0,4) 135(0,5) + // | | + // 32903(0,6) 32903(0,7) + + pldm_entity entities[9]{}; + + entities[0].entity_type = 11521; + entities[1].entity_type = 45; + entities[2].entity_type = 64; + entities[3].entity_type = 67; + entities[4].entity_type = 67; + entities[5].entity_type = 135; + entities[5].entity_container_id = 2; + entities[6].entity_type = 135; + entities[6].entity_container_id = 3; + entities[7].entity_type = 32903; + entities[8].entity_type = 32903; + + auto tree = pldm_entity_association_tree_init(); + + auto l1 = pldm_entity_association_tree_add( + tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL, + false, true, 0xFFFF); + EXPECT_NE(l1, nullptr); + auto l2 = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, l1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); + EXPECT_NE(l2, nullptr); + auto l3 = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, l2, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); + EXPECT_NE(l3, nullptr); + auto l4a = pldm_entity_association_tree_add(tree, &entities[3], 0, l3, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); + EXPECT_NE(l4a, nullptr); + auto l4b = pldm_entity_association_tree_add(tree, &entities[4], 1, l3, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + false, true, 0xFFFF); + EXPECT_NE(l4b, nullptr); + auto l5a = pldm_entity_association_tree_add(tree, &entities[5], 0, l4a, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + true, true, 0xFFFF); + EXPECT_NE(l5a, nullptr); + auto l5b = pldm_entity_association_tree_add(tree, &entities[6], 0, l4b, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + true, true, 0xFFFF); + EXPECT_NE(l5b, nullptr); + + pldm_entity entity{}; + + entity.entity_type = 135; + entity.entity_instance_num = 0; + entity.entity_container_id = 2; + auto result1 = pldm_entity_association_tree_find(tree, &entity, true); + EXPECT_EQ(result1, l5a); + EXPECT_EQ(entities[5].entity_container_id, 4); + EXPECT_EQ(pldm_extract_host_container_id(l5a), 2); + + auto l6a = pldm_entity_association_tree_add(tree, &entities[7], 0, result1, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + true, true, 0xFFFF); + EXPECT_NE(l6a, nullptr); + + entity.entity_type = 135; + entity.entity_instance_num = 0; + entity.entity_container_id = 3; + auto result2 = pldm_entity_association_tree_find(tree, &entity, true); + EXPECT_EQ(result2, l5b); + EXPECT_EQ(entities[6].entity_container_id, 5); + EXPECT_EQ(pldm_extract_host_container_id(l5b), 3); + + auto l7a = pldm_entity_association_tree_add(tree, &entities[8], 0, result2, + PLDM_ENTITY_ASSOCIAION_PHYSICAL, + true, true, 0xFFFF); + EXPECT_NE(l7a, nullptr); + + pldm_entity_association_tree_destroy(tree); +} diff --git a/tests/libpldm_utils_test.cpp b/tests/libpldm_utils_test.cpp index 663a531f9..b238187cd 100644 --- a/tests/libpldm_utils_test.cpp +++ b/tests/libpldm_utils_test.cpp @@ -22,32 +22,26 @@ TEST(Crc8, CheckSumTest) TEST(Ver2string, Ver2string) { - ver32_t version{0x61, 0x10, 0xf7, 0xf3}; + ver32_t version{0xf3, 0xf7, 0x10, 0x61}; const char* vstr = "3.7.10a"; char buffer[1024]; auto rc = ver2str(&version, buffer, sizeof(buffer)); EXPECT_EQ(rc, (signed)std::strlen(vstr)); EXPECT_STREQ(vstr, buffer); - version = {0x00, 0xf0, 0xf0, 0xf1}; - vstr = "1.0.0"; - rc = ver2str(&version, buffer, sizeof(buffer)); - EXPECT_EQ(rc, (signed)std::strlen(vstr)); - EXPECT_STREQ(vstr, buffer); - - version = {0x00, 0xf7, 0x01, 0x10}; + version = {0x10, 0x01, 0xf7, 0x00}; vstr = "10.01.7"; rc = ver2str(&version, buffer, sizeof(buffer)); EXPECT_EQ(rc, (signed)std::strlen(vstr)); EXPECT_STREQ(vstr, buffer); - version = {0x00, 0xff, 0xf1, 0xf3}; + version = {0xf3, 0xf1, 0xff, 0x00}; vstr = "3.1"; rc = ver2str(&version, buffer, sizeof(buffer)); EXPECT_EQ(rc, (signed)std::strlen(vstr)); EXPECT_STREQ(vstr, buffer); - version = {0x61, 0xff, 0xf0, 0xf1}; + version = {0xf1, 0xf0, 0xff, 0x61}; vstr = "1.0a"; rc = ver2str(&version, buffer, sizeof(buffer)); EXPECT_EQ(rc, (signed)std::strlen(vstr));