oem_ibm: Add Slot enable infrastructure in BMC
With this commit PDRs are created for each of these
PCIe slots and adapters which have a corresponding
entry in the entity associate map. The sensor/effector
states are monitored and accordingly D-Bus calls are
sent for enabling a slot, process property change
of a PCIe slot, etc.
Tested By: SIMICS power on/off and reset reload.
Signed-off-by: Manojkiran Eda <manojkiran.eda@gmail.com>
Change-Id: I51b79b75c909ddf2cc29872fec6aa01c2d56b418
diff --git a/common/test/mocked_utils.hpp b/common/test/mocked_utils.hpp
index 1e7cf6e..8e887a5 100644
--- a/common/test/mocked_utils.hpp
+++ b/common/test/mocked_utils.hpp
@@ -68,4 +68,8 @@
MOCK_METHOD(pldm::utils::GetSubTreeResponse, getSubtree,
(const std::string&, int, const std::vector<std::string>&),
(const override));
+
+ MOCK_METHOD(pldm::utils::GetSubTreePathsResponse, getSubTreePaths,
+ (const std::string&, int, const std::vector<std::string>&),
+ (const override));
};
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 2e0ed5a..cf6ecf5 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -54,6 +54,7 @@
'../oem/ibm/libpldmresponder/oem_ibm_handler.cpp',
'../oem/ibm/libpldmresponder/inband_code_update.cpp',
'../oem/ibm/requester/dbus_to_file_handler.cpp',
+ '../oem/ibm/libpldmresponder/collect_slot_vpd.cpp',
'../oem/ibm/libpldmresponder/file_io_type_progress_src.cpp',
'../oem/ibm/libpldmresponder/file_io_type_vpd.cpp',
'../oem/ibm/libpldmresponder/file_io_type_pcie.cpp',
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
index bd65dd2..8215b37 100644
--- a/libpldmresponder/oem_handler.hpp
+++ b/libpldmresponder/oem_handler.hpp
@@ -22,8 +22,10 @@
*
* @param[in] entityType - entity type corresponding to the sensor
* @param[in] entityInstance - entity instance number
+ * @param[in] entityContainerID - container id
* @param[in] stateSetId - state set id
* @param[in] compSensorCnt - composite sensor count
+ * @param[in] sensorId - sensor ID
* @param[out] stateField - The state field data for each of the states,
* equal to composite sensor count in number
*
@@ -34,8 +36,9 @@
virtual int getOemStateSensorReadingsHandler(
pldm::pdr::EntityType entityType,
pldm::pdr::EntityInstance entityInstance,
+ pldm::pdr::ContainerID entityContainerId,
pldm::pdr::StateSetId stateSetId,
- pldm::pdr::CompositeCount compSensorCnt,
+ pldm::pdr::CompositeCount compSensorCnt, uint16_t sensorId,
std::vector<get_sensor_state_field>& stateField) = 0;
/** @brief Interface to set the effecter requested by pldm requester
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 0a0de64..d04bb1e 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -789,13 +789,15 @@
uint16_t entityType{};
uint16_t entityInstance{};
uint16_t stateSetId{};
+ uint16_t containerId{};
if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
- entityType, entityInstance, stateSetId) &&
- oemPlatformHandler != nullptr && !sensorDbusObjMaps.contains(sensorId))
+ entityType, entityInstance, stateSetId, containerId) &&
+ oemPlatformHandler && !sensorDbusObjMaps.contains(sensorId))
{
rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
- entityType, entityInstance, stateSetId, comSensorCnt, stateField);
+ entityType, entityInstance, containerId, stateSetId, comSensorCnt,
+ sensorId, stateField);
}
else
{
@@ -835,7 +837,7 @@
bool isOemStateSensor(Handler& handler, uint16_t sensorId,
uint8_t sensorRearmCount, uint8_t& compSensorCnt,
uint16_t& entityType, uint16_t& entityInstance,
- uint16_t& stateSetId)
+ uint16_t& stateSetId, uint16_t& containerId)
{
pldm_state_sensor_pdr* pdr = nullptr;
@@ -868,6 +870,7 @@
}
auto tmpEntityType = pdr->entity_type;
auto tmpEntityInstance = pdr->entity_instance;
+ auto tmpEntityContainerId = pdr->container_id;
auto tmpCompSensorCnt = pdr->composite_sensor_count;
auto tmpPossibleStates =
reinterpret_cast<state_sensor_possible_states*>(
@@ -892,6 +895,7 @@
entityInstance = tmpEntityInstance;
stateSetId = tmpStateSetId;
compSensorCnt = tmpCompSensorCnt;
+ containerId = tmpEntityContainerId;
return true;
}
else
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index 97e5aa5..6c30c52 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -529,6 +529,7 @@
* @param[out] entityType - entity type
* @param[out] entityInstance - entity instance number
* @param[out] stateSetId - state set id
+ * @param[out] containerId - container id
*
* @return true if the sensor is OEM. All out parameters are invalid
* for a non OEM sensor
@@ -536,7 +537,7 @@
bool isOemStateSensor(Handler& handler, uint16_t sensorId,
uint8_t sensorRearmCount, uint8_t& compSensorCnt,
uint16_t& entityType, uint16_t& entityInstance,
- uint16_t& stateSetId);
+ uint16_t& stateSetId, uint16_t& containerId);
/** @brief Function to check if an effecter falls in OEM range
* An effecter is considered to be oem if either of entity
diff --git a/oem/ibm/libpldmresponder/collect_slot_vpd.cpp b/oem/ibm/libpldmresponder/collect_slot_vpd.cpp
new file mode 100644
index 0000000..2d0f4f9
--- /dev/null
+++ b/oem/ibm/libpldmresponder/collect_slot_vpd.cpp
@@ -0,0 +1,333 @@
+#include "collect_slot_vpd.hpp"
+
+#include "oem_ibm_handler.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+namespace pldm
+{
+namespace responder
+{
+using namespace oem_ibm_platform;
+void SlotHandler::timeOutHandler()
+{
+ info(
+ "Timer expired waiting for Event from Inventory on following pldm_entity: [ {ENTITY_TYP}, {ENTITY_NUM}, {ENTITY_ID} ]",
+ "ENTITY_TYP",
+ static_cast<unsigned>(currentOnGoingSlotEntity.entity_type),
+ "ENTITY_NUM",
+ static_cast<unsigned>(currentOnGoingSlotEntity.entity_instance_num),
+ "ENTITY_ID",
+ static_cast<unsigned>(currentOnGoingSlotEntity.entity_container_id));
+ // Disable the timer
+ timer.setEnabled(false);
+
+ // obtain the sensor Id
+ auto sensorId = pldm::utils::findStateSensorId(
+ pdrRepo, 0, PLDM_ENTITY_SLOT,
+ currentOnGoingSlotEntity.entity_instance_num,
+ currentOnGoingSlotEntity.entity_container_id,
+ PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE);
+
+ // send the sensor event to host with error state
+ sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
+ PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_ERROR,
+ PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_UNKOWN);
+}
+
+void SlotHandler::enableSlot(uint16_t effecterId,
+ const AssociatedEntityMap& fruAssociationMap,
+ uint8_t stateFileValue)
+
+{
+ info("CM: slot enable effecter id: {EFFECTER_ID}", "EFFECTER_ID",
+ effecterId);
+ const pldm_entity entity = getEntityIDfromEffecterID(effecterId);
+
+ for (const auto& [key, value] : fruAssociationMap)
+ {
+ if (entity.entity_instance_num == value.entity_instance_num &&
+ entity.entity_type == value.entity_type &&
+ entity.entity_container_id == value.entity_container_id)
+ {
+ this->currentOnGoingSlotEntity.entity_type = value.entity_type;
+ this->currentOnGoingSlotEntity.entity_instance_num =
+ value.entity_instance_num;
+ this->currentOnGoingSlotEntity.entity_container_id =
+ value.entity_container_id;
+ processSlotOperations(key, value, stateFileValue);
+ }
+ }
+}
+
+void SlotHandler::processSlotOperations(const std::string& slotObjectPath,
+ const pldm_entity& entity,
+ uint8_t stateFieldValue)
+{
+ info("CM: processing the slot operations, SlotObject: {SLOT_OBJ}",
+ "SLOT_OBJ", slotObjectPath);
+
+ std::string adapterObjPath;
+ try
+ {
+ // get the adapter dbus object path from the slot dbus object path
+ adapterObjPath = getAdapterObjPath(slotObjectPath).value();
+ }
+ catch (const std::bad_optional_access& e)
+ {
+ error("Failed to get the adapter dbus object ERROR={ERROR}", "ERROR",
+ e);
+ return;
+ }
+
+ info(
+ "CM: Found an adapter under the slot, adapter object:{ADAPTER_OBJ_PATH}",
+ "ADAPTER_OBJ_PATH", adapterObjPath);
+ // create a presence match for the adpter present property
+ createPresenceMatch(adapterObjPath, entity, stateFieldValue);
+
+ // call the VPD Manager to collect/remove VPD objects
+ callVPDManager(adapterObjPath, stateFieldValue);
+
+ // start the 1 min timer
+ timer.restart(std::chrono::seconds(60));
+}
+
+void SlotHandler::callVPDManager(const std::string& adapterObjPath,
+ uint8_t stateFieldValue)
+{
+ static constexpr auto VPDObjPath = "/com/ibm/VPD/Manager";
+ static constexpr auto VPDInterface = "com.ibm.VPD.Manager";
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ try
+ {
+ auto service =
+ pldm::utils::DBusHandler().getService(VPDObjPath, VPDInterface);
+ if (stateFieldValue == PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_ADD)
+ {
+ auto method = bus.new_method_call(service.c_str(), VPDObjPath,
+ VPDInterface, "CollectFRUVPD");
+ method.append(
+ static_cast<sdbusplus::message::object_path>(adapterObjPath));
+ bus.call_noreply(method, dbusTimeout);
+ }
+ else if (stateFieldValue == PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_REMOVE ||
+ stateFieldValue == PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_REPLACE)
+ {
+ auto method = bus.new_method_call(service.c_str(), VPDObjPath,
+ VPDInterface, "deleteFRUVPD");
+ method.append(
+ static_cast<sdbusplus::message::object_path>(adapterObjPath));
+ bus.call_noreply(method, dbusTimeout);
+ }
+ }
+ catch (const std::exception& e)
+ {
+ error(
+ "failed to make a d-bus call to VPD Manager , Operation = {STATE_FILED_VAL}, ERROR={ERROR}",
+ "STATE_FILED_VAL", (unsigned)stateFieldValue, "ERROR", e);
+ }
+}
+
+std::optional<std::string>
+ SlotHandler::getAdapterObjPath(const std::string& slotObjPath)
+{
+ static constexpr auto searchpath = "/xyz/openbmc_project/inventory";
+ int depth = 0;
+ std::vector<std::string> pcieAdapterInterface = {
+ "xyz.openbmc_project.Inventory.Item.PCIeDevice"};
+ pldm::utils::GetSubTreeResponse response =
+ pldm::utils::DBusHandler().getSubtree(searchpath, depth,
+ pcieAdapterInterface);
+ for (const auto& [objPath, serviceMap] : response)
+ {
+ // An adapter is a child of a PCIe Slot Object
+ if (objPath.contains(slotObjPath))
+ {
+ // Found the Adapter under the slot
+ return objPath;
+ }
+ }
+ return std::nullopt;
+}
+
+void SlotHandler::createPresenceMatch(const std::string& adapterObjectPath,
+ const pldm_entity& entity,
+ uint8_t stateFieldValue)
+{
+ fruPresenceMatch = std::make_unique<sdbusplus::bus::match_t>(
+ pldm::utils::DBusHandler::getBus(),
+ propertiesChanged(adapterObjectPath,
+ "xyz.openbmc_project.Inventory.Item"),
+ [this, adapterObjectPath, stateFieldValue,
+ entity](sdbusplus::message::message& msg) {
+ pldm::utils::DbusChangedProps props{};
+ std::string intf;
+ msg.read(intf, props);
+ const auto itr = props.find("Present");
+ if (itr != props.end())
+ {
+ bool value = std::get<bool>(itr->second);
+ // Present Property is found
+ this->processPresentPropertyChange(value, stateFieldValue,
+ entity);
+ }
+ });
+}
+
+void SlotHandler::processPresentPropertyChange(
+ bool presentValue, uint8_t stateFiledvalue, const pldm_entity& entity)
+{
+ // irrespective of true->false or false->true change, we should stop the
+ // timer
+ timer.setEnabled(false);
+
+ // remove the prence match so that it does not monitor the change
+ // even after we captured the property changed signal
+ fruPresenceMatch = nullptr;
+
+ // obtain the sensor id attached with this slot
+ auto sensorId = pldm::utils::findStateSensorId(
+ pdrRepo, 0, PLDM_ENTITY_SLOT, entity.entity_instance_num,
+ entity.entity_container_id, PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE);
+
+ uint8_t sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_UNKOWN;
+ if (presentValue)
+ {
+ sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_ENABLED;
+ }
+ else
+ {
+ if (stateFiledvalue == PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_REPLACE)
+ {
+ sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_UNKOWN;
+ }
+ else
+ {
+ sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_DISABLED;
+ }
+ }
+ info(
+ "CM: processing the property change from VPD Present value and sensor opState: {CURR_VAL} and {SENSOR_OP_STATE}",
+ "CURR_VAL", presentValue, "SENSOR_OP_STATE", (unsigned)sensorOpState);
+ // set the sensor state based on the stateFieldValue
+ this->sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
+ sensorOpState,
+ PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_UNKOWN);
+}
+
+pldm_entity SlotHandler::getEntityIDfromEffecterID(uint16_t effecterId)
+{
+ pldm_entity parentFruEntity{};
+ uint8_t* pdrData = nullptr;
+ uint32_t pdrSize{};
+ const pldm_pdr_record* record{};
+ do
+ {
+ record = pldm_pdr_find_record_by_type(pdrRepo, PLDM_STATE_EFFECTER_PDR,
+ record, &pdrData, &pdrSize);
+ if (record && !pldm_pdr_record_is_remote(record))
+ {
+ auto pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrData);
+ auto compositeEffecterCount = pdr->composite_effecter_count;
+ auto possible_states_start = pdr->possible_states;
+
+ for (auto effecters = 0x00; effecters < compositeEffecterCount;
+ effecters++)
+ {
+ auto possibleStates =
+ reinterpret_cast<state_effecter_possible_states*>(
+ possible_states_start);
+
+ if (possibleStates->state_set_id ==
+ PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_STATE &&
+ effecterId == pdr->effecter_id)
+ {
+ parentFruEntity.entity_type = pdr->entity_type;
+ parentFruEntity.entity_instance_num = pdr->entity_instance;
+ parentFruEntity.entity_container_id = pdr->container_id;
+
+ return parentFruEntity;
+ }
+ }
+ }
+ } while (record);
+
+ return parentFruEntity;
+}
+
+uint8_t SlotHandler::fetchSlotSensorState(const std::string& slotObjectPath)
+{
+ std::string adapterObjPath;
+ uint8_t sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_UNKOWN;
+
+ try
+ {
+ // get the adapter dbus object path from the slot dbus object path
+ adapterObjPath = getAdapterObjPath(slotObjectPath).value();
+ }
+ catch (const std::bad_optional_access& e)
+ {
+ error(
+ "Failed to get the adapterObjectPath from slotObjectPath : {SLOT_OBJ_PATH} with error ERROR={ERROR}",
+ "SLOT_OBJ_PATH", slotObjectPath, "ERROR", e);
+ return PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_UNKOWN;
+ }
+
+ if (fetchSensorStateFromDbus(adapterObjPath))
+ {
+ sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_ENABLED;
+ }
+ else
+ {
+ sensorOpState = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE_DISABLED;
+ }
+ return sensorOpState;
+}
+
+void SlotHandler::setOemPlatformHandler(
+ pldm::responder::oem_platform::Handler* handler)
+{
+ oemPlatformHandler = handler;
+}
+
+void SlotHandler::sendStateSensorEvent(
+ uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
+ uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
+{
+ pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
+ dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
+ oemPlatformHandler);
+ if (oemIbmPlatformHandler)
+ {
+ oemIbmPlatformHandler->sendStateSensorEvent(
+ sensorId, sensorEventClass, sensorOffset, eventState,
+ prevEventState);
+ }
+}
+
+bool SlotHandler::fetchSensorStateFromDbus(const std::string& adapterObjectPath)
+{
+ static constexpr auto ItemInterface = "xyz.openbmc_project.Inventory.Item";
+
+ try
+ {
+ auto presentProperty =
+ pldm::utils::DBusHandler().getDbusPropertyVariant(
+ adapterObjectPath.c_str(), "Present", ItemInterface);
+ return std::get<bool>(presentProperty);
+ }
+ catch (const std::exception& e)
+ {
+ error(
+ "failed to make a d-bus call to Inventory manager from adapterObjectPath : {ADAPTER_OBJ_PATH} with error ERROR={ERROR}",
+ "ADAPTER_OBJ_PATH", adapterObjectPath, "ERROR", e);
+ }
+
+ return false;
+}
+
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/collect_slot_vpd.hpp b/oem/ibm/libpldmresponder/collect_slot_vpd.hpp
new file mode 100644
index 0000000..0d398ce
--- /dev/null
+++ b/oem/ibm/libpldmresponder/collect_slot_vpd.hpp
@@ -0,0 +1,173 @@
+#pragma once
+
+#include "libpldmresponder/platform.hpp"
+
+#include <libpldm/pdr.h>
+#include <libpldm/platform.h>
+
+#include <sdbusplus/bus/match.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/utility/timer.hpp>
+
+#include <memory>
+
+namespace pldm
+{
+
+using namespace sdbusplus::bus::match::rules;
+
+namespace responder
+{
+
+using ObjectPath = std::string;
+using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
+
+/** @class SlotHandler
+ *
+ * @brief This class performs the necessary operation in pldm for
+ * Slot Enable operation. That includes taking actions on the
+ * setStateEffecterStates calls from Host and also sending
+ * notification to inventory manager application
+ */
+class SlotHandler
+{
+ public:
+ SlotHandler() = delete;
+ ~SlotHandler() = default;
+ SlotHandler(const SlotHandler&) = delete;
+ SlotHandler& operator=(const SlotHandler&) = delete;
+ SlotHandler(SlotHandler&&) = delete;
+ SlotHandler& operator=(SlotHandler&&) = delete;
+
+ /** @brief SlotHandler Constructor
+ *
+ * @param[in] event - reference for the main event loop
+ * @param[in] repo - pointer to the BMC's Primary PDR repo
+ *
+ */
+ SlotHandler(const sdeventplus::Event& event, pldm_pdr* repo) :
+ timer(event,
+ std::bind(std::mem_fn(&SlotHandler::timeOutHandler), this)),
+ pdrRepo(repo)
+ {
+ fruPresenceMatch = nullptr;
+ currentOnGoingSlotEntity.entity_type = 0;
+ currentOnGoingSlotEntity.entity_instance_num = 0;
+ currentOnGoingSlotEntity.entity_container_id = 0;
+ }
+
+ /** @brief Method to be called when enabling a Slot for ADD/REMOVE/REPLACE
+ * @param[in] effecterID - The effecter ID of the effecter that is set from
+ * host
+ * @param[in] fruAssociationMap - the dbus path to pldm entity stored while
+ * creating the pldm fru records
+ * @param[in] stateFieldValue - the current Effecter stateFieldValue
+ */
+ void enableSlot(uint16_t effecterId,
+ const AssociatedEntityMap& fruAssociationMap,
+ uint8_t stateFieldValue);
+
+ /** @brief Method to be used for fetching the slot sensor value
+ * @param[in] slotObjectPath - the dbus object path for slot object
+ * @return - returns the sensor state for the respective slot sensor
+ */
+ uint8_t fetchSlotSensorState(const std::string& slotObjectPath);
+
+ /** @brief Method to set the oem platform handler in SlotHandler class
+ * @param[in] handler - pointer to the oem platform handler
+ */
+ void setOemPlatformHandler(pldm::responder::oem_platform::Handler* handler);
+
+ private:
+ /** @brief call back method called when the timer is expired. This handler
+ * is called when the change of state cannot be made for a slot.
+ */
+ void timeOutHandler();
+
+ /** @brief Abstracted method for obtaining the entityID from effecterID
+ * @param[in] effecterID - The effecterID of the BMC effecter
+ * @return - pldm entity ID for the given effecter ID
+ */
+ pldm_entity getEntityIDfromEffecterID(uint16_t effecterID);
+
+ /** @brief Abstracted method for processing the Slot Operations
+ * @param[in] slotObjPath - The slot dbus object path
+ * @param[in] entity - the current slot pldm entity under operation
+ * @param[in] stateFieldValue - the current Effecter stateFieldValue
+ */
+ void processSlotOperations(const std::string& slotObjectPath,
+ const pldm_entity& entity,
+ uint8_t stateFieldValue);
+
+ /** @brief Method to obtain the Adapter dbus Object Path from Slot Adapter
+ * path
+ * @param[in] slotObjPath - The slot dbus object path
+ * @return - if Successfull, returns the adapter dbus object path
+ */
+ std::optional<std::string>
+ getAdapterObjPath(const std::string& slotObjPath);
+
+ /** @brief Method to call VPD collection & VPD removal API's
+ * @param[in] adapterObjectPath - The adapter D-Bus object path
+ * @param[in] stateFieldvalue - The current stateField value from set
+ * effecter call
+ */
+ void callVPDManager(const std::string& adapterObjPath,
+ uint8_t stateFieldValue);
+
+ /** @brief Method to create a matcher to catch the property change signal
+ * @param[in] adapterObjectPath - The adapter D-Bus object path
+ * @param[in] stateFieldvalue - The current stateField value from set
+ * effecter call
+ * @param[in] entity - the current slot pldm entity under operation
+ */
+ void createPresenceMatch(const std::string& adapterObjectPath,
+ const pldm_entity& entity,
+ uint8_t stateFieldValue);
+
+ /** @brief Method to process the Property change signal from Preset Property
+ * @param[in] presentValue - The current value of present Value
+ * @param[in] stateFieldvalue - The current stateField value from set
+ * effecter call
+ * @param[in] entity - the current slot pldm entity under operation
+ */
+ void processPresentPropertyChange(
+ bool presentValue, uint8_t stateFieldvalue, const pldm_entity& entity);
+
+ /** @brief Get the sensor state from D-Bus
+ * @param[in] adapterObjectPath - reference of the Adapter dbus object path
+ * @return - Boolean value of sensor state
+ */
+
+ bool fetchSensorStateFromDbus(const std::string& adapterObjectPath);
+
+ /* @brief Method to send a state sensor event to Host from SlotHandler class
+ * @param[in] sensorId - sensor id for the event
+ * @param[in] sensorEventClass - sensor event class wrt DSP0248
+ * @param[in] sensorOffset - sensor offset
+ * @param[in] eventState - new event state
+ * @param[in] prevEventState - previous state
+ */
+ void sendStateSensorEvent(uint16_t sensorId,
+ enum sensor_event_class_states sensorEventClass,
+ uint8_t sensorOffset, uint8_t eventState,
+ uint8_t prevEventState);
+
+ pldm::responder::oem_platform::Handler* oemPlatformHandler =
+ nullptr; //!< oem platform handler
+
+ /** @brief pointer to tha matcher for Present State for adapter object*/
+ std::unique_ptr<sdbusplus::bus::match_t> fruPresenceMatch;
+
+ /** @brief Timer used for Slot VPD Collection operation */
+ sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
+
+ /** @brief pointer to BMC's primary PDR repo */
+ const pldm_pdr* pdrRepo;
+
+ /** @brief variable to store the current slot entity under operation */
+ pldm_entity currentOnGoingSlotEntity;
+};
+
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index 6a39328..9721bc1 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -1,11 +1,13 @@
#include "oem_ibm_handler.hpp"
+#include "collect_slot_vpd.hpp"
#include "file_io_type_lid.hpp"
#include "libpldmresponder/file_io.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include <libpldm/entity.h>
#include <libpldm/oem/ibm/entity.h>
+#include <libpldm/pldm.h>
#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/State/BMC/client.hpp>
@@ -24,9 +26,11 @@
int pldm::responder::oem_ibm_platform::Handler::
getOemStateSensorReadingsHandler(
pldm::pdr::EntityType entityType, EntityInstance entityInstance,
- StateSetId stateSetId, CompositeCount compSensorCnt,
+ ContainerID containerId, StateSetId stateSetId,
+ CompositeCount compSensorCnt, uint16_t /*sensorId*/,
std::vector<get_sensor_state_field>& stateField)
{
+ auto& entityAssociationMap = getAssociateEntityMap();
int rc = PLDM_SUCCESS;
stateField.clear();
@@ -38,6 +42,20 @@
{
sensorOpState = fetchBootSide(entityInstance, codeUpdate);
}
+ else if (entityType == PLDM_ENTITY_SLOT &&
+ stateSetId == PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE)
+ {
+ for (const auto& [key, value] : entityAssociationMap)
+ {
+ if (value.entity_type == entityType &&
+ value.entity_instance_num == entityInstance &&
+ value.entity_container_id == containerId)
+ {
+ sensorOpState = slotHandler->fetchSlotSensorState(key);
+ break;
+ }
+ }
+ }
else
{
rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
@@ -53,10 +71,10 @@
oemSetStateEffecterStatesHandler(
uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
uint8_t compEffecterCnt,
- std::vector<set_effecter_state_field>& stateField,
- uint16_t /*effecterId*/)
+ std::vector<set_effecter_state_field>& stateField, uint16_t effecterId)
{
int rc = PLDM_SUCCESS;
+ auto& entityAssociationMap = getAssociateEntityMap();
for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
{
@@ -141,6 +159,11 @@
this, std::placeholders::_1));
}
}
+ else if (stateSetId == PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_STATE)
+ {
+ slotHandler->enableSlot(effecterId, entityAssociationMap,
+ stateField[currState].effecter_state);
+ }
else
{
rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
@@ -206,6 +229,71 @@
repo.addRecord(pdrEntry);
}
+void buildAllSlotEnableEffecterPDR(oem_ibm_platform::Handler* platformHandler,
+ pdr_utils::Repo& repo,
+ const std::vector<std::string>& slotobjpaths)
+{
+ size_t pdrSize = 0;
+ pdrSize = sizeof(pldm_state_effecter_pdr) +
+ sizeof(state_effecter_possible_states);
+ std::vector<uint8_t> entry{};
+ entry.resize(pdrSize);
+ pldm_state_effecter_pdr* pdr =
+ reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
+ if (!pdr)
+ {
+ error("Failed to get record by PDR type, ERROR:{ERR}", "ERR", lg2::hex,
+ static_cast<unsigned>(PLDM_PLATFORM_INVALID_EFFECTER_ID));
+ return;
+ }
+
+ auto& associatedEntityMap = platformHandler->getAssociateEntityMap();
+ for (const auto& entity_path : slotobjpaths)
+ {
+ pdr->hdr.record_handle = 0;
+ pdr->hdr.version = 1;
+ pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
+ pdr->hdr.record_change_num = 0;
+ pdr->hdr.length =
+ sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
+ pdr->terminus_handle = TERMINUS_HANDLE;
+ pdr->effecter_id = platformHandler->getNextEffecterId();
+
+ if (entity_path != "" && associatedEntityMap.contains(entity_path))
+ {
+ pdr->entity_type = associatedEntityMap.at(entity_path).entity_type;
+ pdr->entity_instance =
+ associatedEntityMap.at(entity_path).entity_instance_num;
+ pdr->container_id =
+ associatedEntityMap.at(entity_path).entity_container_id;
+ platformHandler->effecterIdToDbusMap[pdr->effecter_id] =
+ entity_path;
+ }
+ else
+ {
+ // the slots are not present, dont create the PDR
+ continue;
+ }
+ pdr->effecter_semantic_id = 0;
+ pdr->effecter_init = PLDM_NO_INIT;
+ pdr->has_description_pdr = false;
+ pdr->composite_effecter_count = 1;
+
+ auto* possibleStatesPtr = pdr->possible_states;
+ auto possibleStates = reinterpret_cast<state_effecter_possible_states*>(
+ possibleStatesPtr);
+ possibleStates->state_set_id = PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_STATE;
+ possibleStates->possible_states_size = 2;
+ auto state =
+ reinterpret_cast<state_effecter_possible_states*>(possibleStates);
+ state->states[0].byte = 14;
+ pldm::responder::pdr_utils::PdrEntry pdrEntry{};
+ pdrEntry.data = entry.data();
+ pdrEntry.size = pdrSize;
+ repo.addRecord(pdrEntry);
+ }
+}
+
void buildAllCodeUpdateSensorPDR(oem_ibm_platform::Handler* platformHandler,
uint16_t entityType, uint16_t entityInstance,
uint16_t stateSetID, pdr_utils::Repo& repo)
@@ -255,6 +343,66 @@
repo.addRecord(pdrEntry);
}
+void buildAllSlotEnableSensorPDR(oem_ibm_platform::Handler* platformHandler,
+ pdr_utils::Repo& repo,
+ const std::vector<std::string>& slotobjpaths)
+{
+ size_t pdrSize = 0;
+ pdrSize = sizeof(pldm_state_sensor_pdr) +
+ sizeof(state_sensor_possible_states);
+ std::vector<uint8_t> entry{};
+ entry.resize(pdrSize);
+ pldm_state_sensor_pdr* pdr =
+ reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
+ if (!pdr)
+ {
+ error("Failed to get record by PDR type, ERROR:{ERR}", "ERR", lg2::hex,
+ static_cast<unsigned>(PLDM_PLATFORM_INVALID_SENSOR_ID));
+ return;
+ }
+ auto& associatedEntityMap = platformHandler->getAssociateEntityMap();
+ for (const auto& entity_path : slotobjpaths)
+ {
+ pdr->hdr.record_handle = 0;
+ pdr->hdr.version = 1;
+ pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
+ pdr->hdr.record_change_num = 0;
+ pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
+ pdr->terminus_handle = TERMINUS_HANDLE;
+ pdr->sensor_id = platformHandler->getNextSensorId();
+ if (entity_path != "" && associatedEntityMap.contains(entity_path))
+ {
+ pdr->entity_type = associatedEntityMap.at(entity_path).entity_type;
+ pdr->entity_instance =
+ associatedEntityMap.at(entity_path).entity_instance_num;
+ pdr->container_id =
+ associatedEntityMap.at(entity_path).entity_container_id;
+ }
+ else
+ {
+ // the slots are not present, dont create the PDR
+ continue;
+ }
+
+ pdr->sensor_init = PLDM_NO_INIT;
+ pdr->sensor_auxiliary_names_pdr = false;
+ pdr->composite_sensor_count = 1;
+
+ auto* possibleStatesPtr = pdr->possible_states;
+ auto possibleStates =
+ reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
+ possibleStates->state_set_id = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE;
+ possibleStates->possible_states_size = 1;
+ auto state =
+ reinterpret_cast<state_sensor_possible_states*>(possibleStates);
+ state->states[0].byte = 15;
+ pldm::responder::pdr_utils::PdrEntry pdrEntry{};
+ pdrEntry.data = entry.data();
+ pdrEntry.size = pdrSize;
+ repo.addRecord(pdrEntry);
+ }
+}
+
void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
pdr_utils::Repo& repo)
{
@@ -271,6 +419,13 @@
ENTITY_INSTANCE_1,
PLDM_OEM_IBM_SYSTEM_POWER_STATE, repo);
+ static constexpr auto objectPath = "/xyz/openbmc_project/inventory/system";
+ const std::vector<std::string> slotInterface = {
+ "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
+ auto slotPaths = dBusIntf->getSubTreePaths(objectPath, 0, slotInterface);
+ buildAllSlotEnableEffecterPDR(this, repo, slotPaths);
+ buildAllSlotEnableSensorPDR(this, repo, slotPaths);
+
buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
repo);
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index b5749c3..907f2cb 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "collect_slot_vpd.hpp"
+#include "common/utils.hpp"
#include "inband_code_update.hpp"
#include "libpldmresponder/oem_handler.hpp"
#include "libpldmresponder/pdr_utils.hpp"
@@ -20,6 +22,8 @@
{
namespace responder
{
+using ObjectPath = std::string;
+using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
namespace oem_ibm_platform
{
constexpr uint16_t ENTITY_INSTANCE_0 = 0;
@@ -43,13 +47,15 @@
{
public:
Handler(const pldm::utils::DBusHandler* dBusIntf,
- pldm::responder::CodeUpdate* codeUpdate, int mctp_fd,
+ pldm::responder::CodeUpdate* codeUpdate,
+ pldm::responder::SlotHandler* slotHandler, int mctp_fd,
uint8_t mctp_eid, pldm::InstanceIdDb& instanceIdDb,
sdeventplus::Event& event,
pldm::requester::Handler<pldm::requester::Request>* handler) :
oem_platform::Handler(dBusIntf), codeUpdate(codeUpdate),
- platformHandler(nullptr), mctp_fd(mctp_fd), mctp_eid(mctp_eid),
- instanceIdDb(instanceIdDb), event(event), handler(handler),
+ slotHandler(slotHandler), platformHandler(nullptr), mctp_fd(mctp_fd),
+ mctp_eid(mctp_eid), instanceIdDb(instanceIdDb), event(event),
+ handler(handler),
timer(event, std::bind(std::mem_fn(&Handler::setSurvTimer), this,
HYPERVISOR_TID, false)),
hostTransitioningToOff(true)
@@ -146,8 +152,8 @@
int getOemStateSensorReadingsHandler(
pldm::pdr::EntityType entityType,
pldm::pdr::EntityInstance entityInstance,
- pldm::pdr::StateSetId stateSetId,
- pldm::pdr::CompositeCount compSensorCnt,
+ pldm::pdr::ContainerID containerId, pldm::pdr::StateSetId stateSetId,
+ pldm::pdr::CompositeCount compSensorCnt, uint16_t sensorId,
std::vector<get_sensor_state_field>& stateField);
int oemSetStateEffecterStatesHandler(
@@ -181,6 +187,17 @@
return platformHandler->getNextSensorId();
}
+ /** @brief Get std::map associated with the entity
+ * key: object path
+ * value: pldm_entity
+ *
+ * @return std::map<ObjectPath, pldm_entity>
+ */
+ virtual const AssociatedEntityMap& getAssociateEntityMap()
+ {
+ return platformHandler->getAssociateEntityMap();
+ }
+
/** @brief Method to Generate the OEM PDRs
*
* @param[in] repo - instance of concrete implementation of Repo
@@ -298,6 +315,10 @@
~Handler() = default;
pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
+
+ pldm::responder::SlotHandler*
+ slotHandler; //!< pointer to SlotHandler object
+
pldm::responder::platform::Handler*
platformHandler; //!< pointer to PLDM platform handler
@@ -315,6 +336,10 @@
std::unique_ptr<sdeventplus::source::Defer> startUpdateEvent;
std::unique_ptr<sdeventplus::source::Defer> systemRebootEvent;
+ /** @brief Effecterid to dbus object path map
+ */
+ std::unordered_map<uint16_t, std::string> effecterIdToDbusMap;
+
/** @brief reference of main event loop of pldmd, primarily used to schedule
* work
*/
diff --git a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
index a8199f5..ddce8dc 100644
--- a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
+++ b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
@@ -2,9 +2,11 @@
#include "common/utils.hpp"
#include "host-bmc/utils.hpp"
#include "libpldmresponder/event_parser.hpp"
+#include "libpldmresponder/fru.hpp"
#include "libpldmresponder/pdr.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include "libpldmresponder/platform.hpp"
+#include "oem/ibm/libpldmresponder/collect_slot_vpd.hpp"
#include "oem/ibm/libpldmresponder/inband_code_update.hpp"
#include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"
#include "oem/ibm/libpldmresponder/utils.hpp"
@@ -27,6 +29,7 @@
using namespace pldm::responder::pdr_utils;
using namespace pldm::responder::oem_ibm_platform;
using ::testing::Return;
+using ::testing::ReturnRef;
class MockOemUtilsHandler : public oem_ibm_utils::Handler
{
@@ -46,18 +49,30 @@
MOCK_METHOD(void, setVersions, (), (override));
};
+class MockSlotHandler : public SlotHandler
+{
+ public:
+ MockSlotHandler(const sdeventplus::Event& event, pldm_pdr* repo) :
+ SlotHandler(event, repo)
+ {}
+};
+
class MockOemPlatformHandler : public oem_ibm_platform::Handler
{
public:
MockOemPlatformHandler(const pldm::utils::DBusHandler* dBusIntf,
- pldm::responder::CodeUpdate* codeUpdate, int mctp_fd,
- uint8_t mctp_eid, pldm::InstanceIdDb& instanceIdDb,
+ pldm::responder::CodeUpdate* codeUpdate,
+ pldm::responder::SlotHandler* slotHandler,
+ int mctp_fd, uint8_t mctp_eid,
+ pldm::InstanceIdDb& instanceIdDb,
sdeventplus::Event& event) :
- oem_ibm_platform::Handler(dBusIntf, codeUpdate, mctp_fd, mctp_eid,
- instanceIdDb, event, nullptr)
+ oem_ibm_platform::Handler(dBusIntf, codeUpdate, slotHandler, mctp_fd,
+ mctp_eid, instanceIdDb, event, nullptr)
{}
MOCK_METHOD(uint16_t, getNextEffecterId, ());
MOCK_METHOD(uint16_t, getNextSensorId, ());
+ MOCK_METHOD((const AssociatedEntityMap&), getAssociateEntityMap, (),
+ (override));
};
TEST(OemSetStateEffecterStatesHandler, testGoodRequest)
@@ -65,8 +80,10 @@
uint16_t entityID_ = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
uint16_t stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
uint16_t entityInstance_ = 0;
+ uint16_t containerId_ = 0;
uint8_t compSensorCnt_ = 1;
uint16_t effecterId = 0xA;
+ uint16_t sensorId = 0x1;
TestInstanceIdDb instanceIdDb;
sdbusplus::bus_t bus(sdbusplus::bus::new_default());
@@ -76,14 +93,18 @@
auto mockDbusHandler = std::make_unique<MockdBusHandler>();
std::unique_ptr<CodeUpdate> mockCodeUpdate =
std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
- std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ std::unique_ptr<MockOemPlatformHandler> oemPlatformHandler =
+ std::make_unique<MockOemPlatformHandler>(
+ mockDbusHandler.get(), mockCodeUpdate.get(), nullptr, 0x1, 0x9,
+ instanceIdDb, event);
- oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
- mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, instanceIdDb,
- event, nullptr);
+ const AssociatedEntityMap associateMap = {};
+ EXPECT_CALL(*oemPlatformHandler, getAssociateEntityMap())
+ .WillRepeatedly(ReturnRef(associateMap));
auto rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
- entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField);
+ entityID_, entityInstance_, containerId_, stateSetId_, compSensorCnt_,
+ sensorId, stateField);
ASSERT_EQ(rc, PLDM_SUCCESS);
ASSERT_EQ(stateField.size(), 1);
@@ -96,21 +117,24 @@
std::vector<get_sensor_state_field> stateField1;
rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
- entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+ entityID_, entityInstance_, containerId_, stateSetId_, compSensorCnt_,
+ sensorId, stateField1);
ASSERT_EQ(rc, PLDM_SUCCESS);
ASSERT_EQ(stateField1.size(), 1);
ASSERT_EQ(stateField1[0].event_state, tSideNum);
entityInstance_ = 2;
rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
- entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+ entityID_, entityInstance_, containerId_, stateSetId_, compSensorCnt_,
+ sensorId, stateField1);
ASSERT_EQ(rc, PLDM_SUCCESS);
ASSERT_EQ(stateField1[0].event_state, PLDM_SENSOR_UNKNOWN);
entityID_ = 40;
stateSetId_ = 50;
rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
- entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+ entityID_, entityInstance_, containerId_, stateSetId_, compSensorCnt_,
+ sensorId, stateField1);
ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
entityID_ = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
@@ -130,7 +154,6 @@
rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
entityID_, entityInstance_, stateSetId_, compSensorCnt_,
setEffecterStateField, effecterId);
-
ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
entityID_ = 34;
@@ -202,6 +225,7 @@
TEST(generateStateEffecterOEMPDR, testGoodRequest)
{
+ const AssociatedEntityMap associateMap = {};
auto inPDRRepo = pldm_pdr_init();
sdbusplus::bus_t bus(sdbusplus::bus::new_default());
TestInstanceIdDb instanceIdDb;
@@ -209,12 +233,15 @@
auto event = sdeventplus::Event::get_default();
std::unique_ptr<CodeUpdate> mockCodeUpdate =
std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
- std::unique_ptr<oem_ibm_platform::Handler> mockoemPlatformHandler =
+ std::unique_ptr<MockOemPlatformHandler> mockoemPlatformHandler =
std::make_unique<MockOemPlatformHandler>(
- mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, instanceIdDb,
- event);
+ mockDbusHandler.get(), mockCodeUpdate.get(), nullptr, 0x1, 0x9,
+ instanceIdDb, event);
Repo inRepo(inPDRRepo);
+ EXPECT_CALL(*mockoemPlatformHandler, getAssociateEntityMap())
+ .WillRepeatedly(ReturnRef(associateMap));
+
mockoemPlatformHandler->buildOEMPDR(inRepo);
ASSERT_EQ(inRepo.empty(), false);
@@ -307,6 +334,7 @@
TEST(generateStateSensorOEMPDR, testGoodRequest)
{
+ const AssociatedEntityMap associateMap = {};
auto inPDRRepo = pldm_pdr_init();
sdbusplus::bus_t bus(sdbusplus::bus::new_default());
TestInstanceIdDb instanceIdDb;
@@ -315,10 +343,12 @@
auto event = sdeventplus::Event::get_default();
std::unique_ptr<CodeUpdate> mockCodeUpdate =
std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
- std::unique_ptr<oem_ibm_platform::Handler> mockoemPlatformHandler =
+ std::unique_ptr<MockOemPlatformHandler> mockoemPlatformHandler =
std::make_unique<MockOemPlatformHandler>(
- mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, instanceIdDb,
- event);
+ mockDbusHandler.get(), mockCodeUpdate.get(), nullptr, 0x1, 0x9,
+ instanceIdDb, event);
+ EXPECT_CALL(*mockoemPlatformHandler, getAssociateEntityMap())
+ .WillRepeatedly(ReturnRef(associateMap));
Repo inRepo(inPDRRepo);
mockoemPlatformHandler->buildOEMPDR(inRepo);
ASSERT_EQ(inRepo.empty(), false);
@@ -416,8 +446,8 @@
std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
std::unique_ptr<oem_ibm_platform::Handler> mockoemPlatformHandler =
std::make_unique<MockOemPlatformHandler>(
- mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, instanceIdDb,
- event);
+ mockDbusHandler.get(), mockCodeUpdate.get(), nullptr, 0x1, 0x9,
+ instanceIdDb, event);
std::string dbuspath = "/inventory/system1/chassis1/motherboard1/dcm0";
mockoemPlatformHandler->updateOemDbusPaths(dbuspath);
EXPECT_EQ(dbuspath, "/inventory/system/chassis/motherboard/dcm0");
diff --git a/pldmd/oem_ibm.hpp b/pldmd/oem_ibm.hpp
index 67ad482..6003125 100644
--- a/pldmd/oem_ibm.hpp
+++ b/pldmd/oem_ibm.hpp
@@ -75,6 +75,7 @@
oemIbmFruHandler->setIBMFruHandler(fruHandler);
createCodeUpdate();
+ createSlotHandler();
createOemPlatformHandler();
createOemIbmUtilsHandler();
codeUpdate->setOemPlatformHandler(oemPlatformHandler.get());
@@ -82,6 +83,7 @@
hostPDRHandler->setOemUtilsHandler(oemUtilsHandler.get());
platformHandler->setOemPlatformHandler(oemPlatformHandler.get());
baseHandler->setOemPlatformHandler(oemPlatformHandler.get());
+ slotHandler->setOemPlatformHandler(oemPlatformHandler.get());
createOemIbmPlatformHandler();
oemIbmPlatformHandler->setPlatformHandler(platformHandler);
@@ -99,6 +101,13 @@
codeUpdate->clearDirPath(LID_STAGING_DIR);
}
+ /** @brief Method for creating slot handler */
+ void createSlotHandler()
+ {
+ slotHandler =
+ std::make_unique<pldm::responder::SlotHandler>(event, repo);
+ }
+
/** @brief Method for creating oemPlatformHandler
*
* This method also assigns the oemPlatformHandler to the below
@@ -106,10 +115,9 @@
*/
void createOemPlatformHandler()
{
- oemPlatformHandler =
- std::make_unique<responder::oem_ibm_platform::Handler>(
- dBusIntf, codeUpdate.get(), mctp_fd, mctp_eid, instanceIdDb,
- event, reqHandler);
+ oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
+ dBusIntf, codeUpdate.get(), slotHandler.get(), mctp_fd, mctp_eid,
+ instanceIdDb, event, reqHandler);
}
/** @brief Method for creating oemIbmPlatformHandler */
@@ -195,6 +203,9 @@
/** @brief pointer to the CodeUpdate class*/
std::unique_ptr<pldm::responder::CodeUpdate> codeUpdate{};
+ /** @brief pointer to the SlotHanlder class*/
+ std::unique_ptr<pldm::responder::SlotHandler> slotHandler{};
+
/** @brief oem IBM Platform handler*/
pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler = nullptr;