oem ibm: infrastructure for oem handlers
1. This commit adds the framework for an oem handler
which can be used by specific oem use-cases
for implementing various commands.
2. This commit adds implementation for getStateSensorReadings
and setStateEffecterStates commands for oem state sets.
3. Also adds implementation for inband code update.
Change-Id: Ib38a66ee381dd06b93f6a9313d51de1c23e6ee65
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/common/types.hpp b/common/types.hpp
index c2b3510..254c37a 100644
--- a/common/types.hpp
+++ b/common/types.hpp
@@ -34,6 +34,7 @@
using EntityType = uint16_t;
using EntityInstance = uint16_t;
using ContainerID = uint16_t;
+using StateSetId = uint16_t;
using CompositeCount = uint8_t;
using SensorOffset = uint8_t;
using EventState = uint8_t;
diff --git a/common/utils.hpp b/common/utils.hpp
index 7478aab..664169d 100644
--- a/common/utils.hpp
+++ b/common/utils.hpp
@@ -4,6 +4,8 @@
#include "libpldm/bios.h"
#include "libpldm/platform.h"
+#include "types.hpp"
+
#include <stdint.h>
#include <systemd/sd-bus.h>
#include <unistd.h>
@@ -136,6 +138,10 @@
uint64_t, double, std::string>;
using DbusProp = std::string;
using DbusChangedProps = std::map<DbusProp, PropertyValue>;
+using DBusInterfaceAdded = std::vector<
+ std::pair<pldm::dbus::Interface,
+ std::vector<std::pair<pldm::dbus::Property,
+ std::variant<pldm::dbus::Property>>>>>;
/**
* @brief The interface for DBusHandler
diff --git a/libpldm/entity.h b/libpldm/entity.h
index 600946e..3cf0a23 100644
--- a/libpldm/entity.h
+++ b/libpldm/entity.h
@@ -139,6 +139,10 @@
/* Logical */
PLDM_ENTITY_SYSTEM_LOGICAL = 11521,
+
+ /* OEM ranges */
+ PLDM_OEM_ENTITY_TYPE_START = 24576,
+ PLDM_OEM_ENTITY_TYPE_END = 32767,
};
#ifdef __cplusplus
diff --git a/libpldm/state_set.h b/libpldm/state_set.h
index 3a0528e..009b0df 100644
--- a/libpldm/state_set.h
+++ b/libpldm/state_set.h
@@ -162,6 +162,11 @@
PLDM_SW_TERM_GRACEFUL_SHUTDOWN = 7,
PLDM_SW_TERM_TERMINATION_REQUEST_FAILED = 8,
};
+
+/* OEM ranges */
+#define PLDM_OEM_STATE_SET_ID_START 32768
+#define PLDM_OEM_STATE_SET_ID_END 65535
+
#ifdef __cplusplus
}
#endif
diff --git a/libpldm/states.h b/libpldm/states.h
index ca20acd..a89648d 100644
--- a/libpldm/states.h
+++ b/libpldm/states.h
@@ -7,13 +7,6 @@
#include "pldm_types.h"
-/** @brief PLDM state set ids
- */
-enum pldm_state_set_ids {
- PLDM_BOOT_PROGRESS_STATE = 196,
- PLDM_SYSTEM_POWER_STATE = 260,
-};
-
/** @brief PLDM enums for the boot progress state set
*/
enum pldm_boot_progress_states {
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 50ca692..794a5e4 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -34,7 +34,9 @@
'../oem/ibm/libpldmresponder/file_io_type_pel.cpp',
'../oem/ibm/libpldmresponder/file_io_type_dump.cpp',
'../oem/ibm/libpldmresponder/file_io_type_cert.cpp',
- '../oem/ibm/libpldmresponder/platform_oem_ibm.cpp'
+ '../oem/ibm/libpldmresponder/platform_oem_ibm.cpp',
+ '../oem/ibm/libpldmresponder/oem_ibm_handler.cpp',
+ '../oem/ibm/libpldmresponder/inband_code_update.cpp'
]
endif
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
new file mode 100644
index 0000000..52d0027
--- /dev/null
+++ b/libpldmresponder/oem_handler.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "common/types.hpp"
+#include "common/utils.hpp"
+#include "pldmd/handler.hpp"
+
+namespace pldm
+{
+
+using namespace pdr;
+
+namespace responder
+{
+
+namespace oem_platform
+{
+
+class Handler : public CmdHandler
+{
+ public:
+ Handler(const pldm::utils::DBusHandler* dBusIntf) : dBusIntf(dBusIntf)
+ {}
+
+ /** @brief Interface to get the state sensor readings requested by pldm
+ * requester for OEM types. Each specific type should implement a handler
+ * of it's own
+ *
+ * @param[in] entityType - entity type corresponding to the sensor
+ * @param[in] entityInstance - entity instance number
+ * @param[in] stateSetId - state set id
+ * @param[in] compSensorCnt - composite sensor count
+ * @param[out] stateField - The state field data for each of the states,
+ * equal to composite sensor count in number
+ *
+ * @return - Success or failure in getting the states. Returns failure in
+ * terms of PLDM completion codes if fetching atleast one state
+ * fails
+ */
+ virtual int getOemStateSensorReadingsHandler(
+ EntityType entityType, EntityInstance entityInstance,
+ StateSetId stateSetId, CompositeCount compSensorCnt,
+ std::vector<get_sensor_state_field>& stateField) = 0;
+
+ /** @brief Interface to set the effecter requested by pldm requester
+ * for OEM types. Each individual oem type should implement
+ * it's own handler.
+ *
+ * @param[in] entityType - entity type corresponding to the effecter id
+ * @param[in] entityInstance - entity instance
+ * @param[in] stateSetId - state set id
+ * @param[in] compEffecterCnt - composite effecter count
+ * param[in] stateField - The state field data for each of the states,
+ * equal to compEffecterCnt in number
+ *
+ * @return - Success or failure in setting the states.Returns failure in
+ * terms of PLDM completion codes if atleast one state fails to
+ * be set
+ */
+
+ virtual int oemSetStateEffecterStatesHandler(
+ EntityType entityType, EntityInstance entityInstance,
+ StateSetId stateSetId, CompositeCount compEffecterCnt,
+ const std::vector<set_effecter_state_field>& stateField) = 0;
+
+ virtual ~Handler() = default;
+
+ protected:
+ const pldm::utils::DBusHandler* dBusIntf;
+};
+
+} // namespace oem_platform
+
+} // namespace responder
+
+} // namespace pldm
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index d2d1d6e..984d79b 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -1,6 +1,9 @@
#include "platform.hpp"
+#include "libpldm/entity.h"
+#include "libpldm/state_set.h"
+
#include "common/types.hpp"
#include "common/utils.hpp"
#include "event_parser.hpp"
@@ -244,9 +247,24 @@
stateField.resize(compEffecterCnt);
const pldm::utils::DBusHandler dBusIntf;
- rc = platform_state_effecter::setStateEffecterStatesHandler<
- pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
- stateField);
+ uint16_t entityType{};
+ uint16_t entityInstance{};
+ uint16_t stateSetId{};
+
+ if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
+ entityInstance, stateSetId) &&
+ oemPlatformHandler != nullptr)
+ {
+ rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+ entityType, entityInstance, stateSetId, compEffecterCnt,
+ stateField);
+ }
+ else
+ {
+ rc = platform_state_effecter::setStateEffecterStatesHandler<
+ pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
+ stateField);
+ }
if (rc != PLDM_SUCCESS)
{
return CmdHandler::ccOnlyResponse(request, rc);
@@ -583,13 +601,29 @@
}
// 0x01 to 0x08
- uint8_t sensorRearmCout = getBitfieldCount(sensorRearm);
- std::vector<get_sensor_state_field> stateField(sensorRearmCout);
+ uint8_t sensorRearmCount = getBitfieldCount(sensorRearm);
+ std::vector<get_sensor_state_field> stateField(sensorRearmCount);
uint8_t comSensorCnt{};
const pldm::utils::DBusHandler dBusIntf;
- rc = platform_state_sensor::getStateSensorReadingsHandler<
- pldm::utils::DBusHandler, Handler>(
- dBusIntf, *this, sensorId, sensorRearmCout, comSensorCnt, stateField);
+
+ uint16_t entityType{};
+ uint16_t entityInstance{};
+ uint16_t stateSetId{};
+
+ if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
+ entityType, entityInstance, stateSetId) &&
+ oemPlatformHandler != nullptr)
+ {
+ rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+ entityType, entityInstance, stateSetId, comSensorCnt, stateField);
+ }
+ else
+ {
+ rc = platform_state_sensor::getStateSensorReadingsHandler<
+ pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId,
+ sensorRearmCount, comSensorCnt,
+ stateField);
+ }
if (rc != PLDM_SUCCESS)
{
@@ -611,6 +645,134 @@
return response;
}
+bool isOemStateSensor(Handler& handler, uint16_t sensorId,
+ uint8_t sensorRearmCount, uint8_t& compSensorCnt,
+ uint16_t& entityType, uint16_t& entityInstance,
+ uint16_t& stateSetId)
+{
+ pldm_state_sensor_pdr* pdr = nullptr;
+
+ std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
+ pldm_pdr_init(), pldm_pdr_destroy);
+ Repo stateSensorPDRs(stateSensorPdrRepo.get());
+ getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
+ if (stateSensorPDRs.empty())
+ {
+ std::cerr << "Failed to get record by PDR type\n";
+ return false;
+ }
+
+ PdrEntry pdrEntry{};
+ auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
+ while (pdrRecord)
+ {
+ pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
+ assert(pdr != NULL);
+ if (pdr->sensor_id != sensorId)
+ {
+ pdr = nullptr;
+ pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
+ continue;
+ }
+ auto tmpEntityType = pdr->entity_type;
+ auto tmpEntityInstance = pdr->entity_instance;
+ auto tmpCompSensorCnt = pdr->composite_sensor_count;
+ auto tmpPossibleStates =
+ reinterpret_cast<state_sensor_possible_states*>(
+ pdr->possible_states);
+ auto tmpStateSetId = tmpPossibleStates->state_set_id;
+
+ if (sensorRearmCount > tmpCompSensorCnt)
+ {
+ std::cerr << "The requester sent wrong sensorRearm"
+ << " count for the sensor, SENSOR_ID=" << sensorId
+ << "SENSOR_REARM_COUNT=" << (uint16_t)sensorRearmCount
+ << "\n";
+ break;
+ }
+
+ if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
+ tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
+ (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
+ tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
+ {
+ entityType = tmpEntityType;
+ entityInstance = tmpEntityInstance;
+ stateSetId = tmpStateSetId;
+ compSensorCnt = tmpCompSensorCnt;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return false;
+}
+
+bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
+ uint8_t compEffecterCnt, uint16_t& entityType,
+ uint16_t& entityInstance, uint16_t& stateSetId)
+{
+ pldm_state_effecter_pdr* pdr = nullptr;
+
+ std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
+ pldm_pdr_init(), pldm_pdr_destroy);
+ Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
+ getRepoByType(handler.getRepo(), stateEffecterPDRs,
+ PLDM_STATE_EFFECTER_PDR);
+ if (stateEffecterPDRs.empty())
+ {
+ std::cerr << "Failed to get record by PDR type\n";
+ return false;
+ }
+
+ PdrEntry pdrEntry{};
+ auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
+ while (pdrRecord)
+ {
+ pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
+ assert(pdr != NULL);
+ if (pdr->effecter_id != effecterId)
+ {
+ pdr = nullptr;
+ pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
+ continue;
+ }
+
+ auto tmpEntityType = pdr->entity_type;
+ auto tmpEntityInstance = pdr->entity_instance;
+ auto tmpPossibleStates =
+ reinterpret_cast<state_effecter_possible_states*>(
+ pdr->possible_states);
+ auto tmpStateSetId = tmpPossibleStates->state_set_id;
+
+ if (compEffecterCnt > pdr->composite_effecter_count)
+ {
+ std::cerr << "The requester sent wrong composite effecter"
+ << " count for the effecter, EFFECTER_ID=" << effecterId
+ << "COMP_EFF_CNT=" << (uint16_t)compEffecterCnt << "\n";
+ return false;
+ }
+
+ if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
+ tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
+ (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
+ tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
+ {
+ entityType = tmpEntityType;
+ entityInstance = tmpEntityInstance;
+ stateSetId = tmpStateSetId;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return false;
+}
+
} // namespace platform
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index ef2434d..09418cd 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -13,6 +13,7 @@
#include "host-bmc/host_pdr_handler.hpp"
#include "libpldmresponder/pdr.hpp"
#include "libpldmresponder/pdr_utils.hpp"
+#include "oem_handler.hpp"
#include "pldmd/handler.hpp"
#include <stdint.h>
@@ -55,12 +56,14 @@
const std::string& pdrJsonsDir, pldm_pdr* repo,
HostPDRHandler* hostPDRHandler,
DbusToPLDMEvent* dbusToPLDMEventHandler, fru::Handler* fruHandler,
+ pldm::responder::oem_platform::Handler* oemPlatformHandler,
bool buildPDRLazily = false,
const std::optional<EventMap>& addOnHandlersMap = std::nullopt) :
pdrRepo(repo),
hostPDRHandler(hostPDRHandler),
dbusToPLDMEventHandler(dbusToPLDMEventHandler), fruHandler(fruHandler),
- dBusIntf(dBusIntf), pdrJsonsDir(pdrJsonsDir), pdrCreated(false)
+ dBusIntf(dBusIntf), oemPlatformHandler(oemPlatformHandler),
+ pdrJsonsDir(pdrJsonsDir), pdrCreated(false)
{
if (!buildPDRLazily)
{
@@ -441,10 +444,49 @@
DbusToPLDMEvent* dbusToPLDMEventHandler;
fru::Handler* fruHandler;
const pldm::utils::DBusHandler* dBusIntf;
+ pldm::responder::oem_platform::Handler* oemPlatformHandler;
std::string pdrJsonsDir;
bool pdrCreated;
};
+/** @brief Function to check if a sensor falls in OEM range
+ * A sensor is considered to be oem if either of entity
+ * type or state set or both falls in oem range
+ *
+ * @param[in] handler - the interface object
+ * @param[in] sensorId - sensor id
+ * @param[in] sensorRearmCount - sensor rearm count
+ * @param[out] compSensorCnt - composite sensor count
+ * @param[out] entityType - entity type
+ * @param[out] entityInstance - entity instance number
+ * @param[out] stateSetId - state set id
+ *
+ * @return true if the sensor is OEM. All out parameters are invalid
+ * for a non OEM sensor
+ */
+bool isOemStateSensor(Handler& handler, uint16_t sensorId,
+ uint8_t sensorRearmCount, uint8_t& compSensorCnt,
+ uint16_t& entityType, uint16_t& entityInstance,
+ uint16_t& stateSetId);
+
+/** @brief Function to check if an effecter falls in OEM range
+ * An effecter is considered to be oem if either of entity
+ * type or state set or both falls in oem range
+ *
+ * @param[in] handler - the interface object
+ * @param[in] effecterId - effecter id
+ * @param[in] compEffecterCnt - composite effecter count
+ * @param[out] entityType - entity type
+ * @param[out] entityInstance - entity instance number
+ * @param[out] stateSetId - state set id
+ *
+ * @return true if the effecter is OEM. All out parameters are invalid
+ * for a non OEM effecter
+ */
+bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
+ uint8_t compEffecterCnt, uint16_t& entityType,
+ uint16_t& entityInstance, uint16_t& stateSetId);
+
} // namespace platform
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io.hpp b/oem/ibm/libpldmresponder/file_io.hpp
index 771d038..9f6492c 100644
--- a/oem/ibm/libpldmresponder/file_io.hpp
+++ b/oem/ibm/libpldmresponder/file_io.hpp
@@ -7,6 +7,7 @@
#include "oem/ibm/libpldm/host.h"
#include "common/utils.hpp"
+#include "oem_ibm_handler.hpp"
#include "pldmd/handler.hpp"
#include <fcntl.h>
@@ -157,7 +158,8 @@
class Handler : public CmdHandler
{
public:
- Handler()
+ Handler(oem_platform::Handler* oemPlatformHandler) :
+ oemPlatformHandler(oemPlatformHandler)
{
handlers.emplace(PLDM_READ_FILE_INTO_MEMORY,
[this](const pldm_msg* request, size_t payloadLength) {
@@ -312,6 +314,9 @@
* @return PLDM response message
*/
Response newFileAvailable(const pldm_msg* request, size_t payloadLength);
+
+ private:
+ oem_platform::Handler* oemPlatformHandler;
};
} // namespace oem_ibm
diff --git a/oem/ibm/libpldmresponder/inband_code_update.cpp b/oem/ibm/libpldmresponder/inband_code_update.cpp
new file mode 100644
index 0000000..f17b209
--- /dev/null
+++ b/oem/ibm/libpldmresponder/inband_code_update.cpp
@@ -0,0 +1,217 @@
+#include "inband_code_update.hpp"
+
+#include "oem_ibm_handler.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Dump/NewDump/server.hpp>
+
+#include <exception>
+
+namespace pldm
+{
+
+namespace responder
+{
+using namespace oem_ibm_platform;
+
+std::string CodeUpdate::fetchCurrentBootSide()
+{
+ return currBootSide;
+}
+
+std::string CodeUpdate::fetchNextBootSide()
+{
+ return nextBootSide;
+}
+
+int CodeUpdate::setCurrentBootSide(const std::string& currSide)
+{
+ currBootSide = currSide;
+ return PLDM_SUCCESS;
+}
+
+int CodeUpdate::setNextBootSide(const std::string& nextSide)
+{
+ nextBootSide = nextSide;
+ std::string objPath{};
+ if (nextBootSide == currBootSide)
+ {
+ objPath = runningVersion;
+ }
+ else
+ {
+ objPath = nonRunningVersion;
+ }
+ if (objPath.empty())
+ {
+ std::cerr << "no nonRunningVersion present \n";
+ return PLDM_PLATFORM_INVALID_STATE_VALUE;
+ }
+
+ pldm::utils::DBusMapping dbusMapping{objPath, redundancyIntf, "Priority",
+ "uint8_t"};
+ uint8_t val = 0;
+ pldm::utils::PropertyValue value = static_cast<uint8_t>(val);
+ try
+ {
+ dBusIntf->setDbusProperty(dbusMapping, value);
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "failed to set the next boot side to " << objPath.c_str()
+ << " ERROR=" << e.what() << "\n";
+ return PLDM_ERROR;
+ }
+ return PLDM_SUCCESS;
+}
+
+void CodeUpdate::setVersions()
+{
+ static constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
+ static constexpr auto functionalObjPath =
+ "/xyz/openbmc_project/software/functional";
+ static constexpr auto activeObjPath =
+ "/xyz/openbmc_project/software/active";
+ static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
+
+ auto& bus = dBusIntf->getBus();
+
+ try
+ {
+ auto method = bus.new_method_call(mapperService, functionalObjPath,
+ propIntf, "Get");
+ method.append("xyz.openbmc_project.Association", "endpoints");
+ std::variant<std::vector<std::string>> paths;
+
+ auto reply = bus.call(method);
+ reply.read(paths);
+
+ runningVersion = std::get<std::vector<std::string>>(paths)[0];
+
+ auto method1 =
+ bus.new_method_call(mapperService, activeObjPath, propIntf, "Get");
+ method1.append("xyz.openbmc_project.Association", "endpoints");
+
+ auto reply1 = bus.call(method1);
+ reply1.read(paths);
+ for (const auto& path : std::get<std::vector<std::string>>(paths))
+ {
+ if (path != runningVersion)
+ {
+ nonRunningVersion = path;
+ break;
+ }
+ }
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "failed to make a d-bus call to Object Mapper "
+ "Association, ERROR="
+ << e.what() << "\n";
+ return;
+ }
+
+ using namespace sdbusplus::bus::match::rules;
+ captureNextBootSideChange.push_back(
+ std::make_unique<sdbusplus::bus::match::match>(
+ pldm::utils::DBusHandler::getBus(),
+ propertiesChanged(runningVersion, redundancyIntf),
+ [this](sdbusplus::message::message& msg) {
+ DbusChangedProps props;
+ std::string iface;
+ msg.read(iface, props);
+ processPriorityChangeNotification(props);
+ }));
+ fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
+ pldm::utils::DBusHandler::getBus(),
+ "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+ "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
+ [this](sdbusplus::message::message& msg) {
+ DBusInterfaceAdded interfaces;
+ sdbusplus::message::object_path path;
+ msg.read(path, interfaces);
+ for (auto& interface : interfaces)
+ {
+ if (interface.first ==
+ "xyz.openbmc_project.Software.Activation")
+ {
+ newImageId = path.str;
+ break;
+ }
+ }
+ });
+}
+
+void CodeUpdate::processPriorityChangeNotification(
+ const DbusChangedProps& chProperties)
+{
+ static constexpr auto propName = "Priority";
+ const auto it = chProperties.find(propName);
+ if (it == chProperties.end())
+ {
+ return;
+ }
+ uint8_t newVal = std::get<uint8_t>(it->second);
+ nextBootSide = (newVal == 0) ? currBootSide
+ : ((currBootSide == Tside) ? Pside : Tside);
+}
+
+void CodeUpdate::setOemPlatformHandler(
+ pldm::responder::oem_platform::Handler* handler)
+{
+ oemPlatformHandler = handler;
+}
+
+uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate)
+{
+ uint8_t sensorOpState = tSideNum;
+
+ if (entityInstance == 0)
+ {
+ auto currSide = codeUpdate->fetchCurrentBootSide();
+ if (currSide == Pside)
+ {
+ sensorOpState = pSideNum;
+ }
+ }
+ else if (entityInstance == 1)
+ {
+ auto nextSide = codeUpdate->fetchNextBootSide();
+ if (nextSide == Pside)
+ {
+ sensorOpState = pSideNum;
+ }
+ }
+ else
+ {
+ sensorOpState = PLDM_SENSOR_UNKNOWN;
+ }
+
+ return sensorOpState;
+}
+
+int setBootSide(uint16_t entityInstance, uint8_t currState,
+ const std::vector<set_effecter_state_field>& stateField,
+ CodeUpdate* codeUpdate)
+{
+ int rc = PLDM_SUCCESS;
+ auto side = (stateField[currState].effecter_state == pSideNum) ? "P" : "T";
+
+ if (entityInstance == 0)
+ {
+ rc = codeUpdate->setCurrentBootSide(side);
+ }
+ else if (entityInstance == 1)
+ {
+ rc = codeUpdate->setNextBootSide(side);
+ }
+ else
+ {
+ rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
+ }
+ return rc;
+}
+
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/inband_code_update.hpp b/oem/ibm/libpldmresponder/inband_code_update.hpp
new file mode 100644
index 0000000..6607de0
--- /dev/null
+++ b/oem/ibm/libpldmresponder/inband_code_update.hpp
@@ -0,0 +1,128 @@
+#pragma once
+
+#include "common/utils.hpp"
+#include "libpldmresponder/platform.hpp"
+
+#include <string>
+
+using namespace pldm::utils;
+namespace pldm
+{
+namespace responder
+{
+
+static constexpr uint8_t pSideNum = 1;
+static constexpr uint8_t tSideNum = 2;
+static constexpr auto Pside = "P";
+static constexpr auto Tside = "T";
+
+static constexpr auto redundancyIntf =
+ "xyz.openbmc_project.Software.RedundancyPriority";
+
+/** @class CodeUpdate
+ *
+ * @brief This class performs the necessary operation in pldm for
+ * inband code update. That includes taking actions on the
+ * setStateEffecterStates calls from Host and also sending
+ * notification to phosphor-software-manager app
+ */
+class CodeUpdate
+{
+ public:
+ /** @brief Constructor to create an inband codeupdate object
+ * @param[in] dBusIntf - D-Bus handler pointer
+ */
+ CodeUpdate(const pldm::utils::DBusHandler* dBusIntf) : dBusIntf(dBusIntf)
+ {
+ currBootSide = Tside;
+ nextBootSide = Tside;
+ }
+
+ /* @brief Method to return the current boot side
+ */
+ std::string fetchCurrentBootSide();
+
+ /* @brief Method to return the next boot side
+ */
+ std::string fetchNextBootSide();
+
+ /* @brief Method to set the current boot side or
+ * perform a rename operation on current boot side
+ * @param[in] currSide - current side to be set to
+ * @return PLDM_SUCCESS codes
+ */
+ int setCurrentBootSide(const std::string& currSide);
+
+ /* @brief Method to set the next boot side
+ * @param[in] nextSide - next boot side to be set to
+ * @return PLDM_SUCCESS codes
+ */
+ int setNextBootSide(const std::string& nextSide);
+
+ /* @brief Method to set the running and non-running
+ * images
+ */
+ virtual void setVersions();
+
+ /* @brief Method to return the newly upoaded image id in
+ * /tmp
+ */
+ std::string fetchnewImageId()
+ {
+ return newImageId;
+ }
+
+ /* @brief Method to set the oem platform handler in CodeUpdate class */
+ void setOemPlatformHandler(pldm::responder::oem_platform::Handler* handler);
+
+ virtual ~CodeUpdate()
+ {}
+
+ private:
+ std::string currBootSide; //!< current boot side
+ std::string nextBootSide; //!< next boot side
+ std::string runningVersion; //!< currently running image
+ std::string nonRunningVersion; //!< alternate image
+ std::string newImageId; //!< new image id
+ bool codeUpdateInProgress =
+ false; //!< indicates whether codeupdate is going on
+ const pldm::utils::DBusHandler* dBusIntf; //!< D-Bus handler
+ std::vector<std::unique_ptr<sdbusplus::bus::match::match>>
+ captureNextBootSideChange; //!< vector to catch the D-Bus property
+ //!< change for next boot side
+ std::unique_ptr<sdbusplus::bus::match::match>
+ fwUpdateMatcher; //!< pointer to capture the interface added signal for
+ //!< new image
+ pldm::responder::oem_platform::Handler*
+ oemPlatformHandler; //!< oem platform handler
+
+ /* @brief Method to take action when the subscribed D-Bus property is
+ * changed
+ * @param[in] chProperties - list of properties which have changed
+ * @return - none
+ */
+
+ void
+ processPriorityChangeNotification(const DbusChangedProps& chProperties);
+};
+
+/* @brief Method to fetch current or next boot side
+ * @param[in] entityInstance - entity instance for the sensor
+ * @param[in] codeUpdate - pointer to the CodeUpdate object
+ *
+ * @return - boot side
+ */
+uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate);
+
+/* @brief Method to set current or next boot side
+ * @param[in] entityInstance - entity instance for the effecter
+ * @param[in] currState - state to be set
+ * @param[in] stateField - state field set as sent by Host
+ * @return - PLDM_SUCCESS codes
+ */
+int setBootSide(uint16_t entityInstance, uint8_t currState,
+ const std::vector<set_effecter_state_field>& stateField,
+ CodeUpdate* codeUpdate);
+
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
new file mode 100644
index 0000000..2e6bd4c
--- /dev/null
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -0,0 +1,83 @@
+#include "oem_ibm_handler.hpp"
+
+#include "libpldm/entity.h"
+
+namespace pldm
+{
+
+namespace responder
+{
+
+namespace oem_ibm_platform
+{
+
+int pldm::responder::oem_ibm_platform::Handler::
+ getOemStateSensorReadingsHandler(
+ EntityType entityType, EntityInstance entityInstance,
+ StateSetId stateSetId, CompositeCount compSensorCnt,
+ std::vector<get_sensor_state_field>& stateField)
+{
+ int rc = PLDM_SUCCESS;
+ stateField.clear();
+
+ for (size_t i = 0; i < compSensorCnt; i++)
+ {
+ uint8_t sensorOpState{};
+ if (entityType == PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER &&
+ stateSetId == PLDM_OEM_IBM_BOOT_STATE)
+ {
+ sensorOpState = fetchBootSide(entityInstance, codeUpdate);
+ }
+ else
+ {
+ rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
+ break;
+ }
+ stateField.push_back({PLDM_SENSOR_ENABLED, PLDM_SENSOR_UNKNOWN,
+ PLDM_SENSOR_UNKNOWN, sensorOpState});
+ }
+ return rc;
+}
+
+int pldm::responder::oem_ibm_platform::Handler::
+ oemSetStateEffecterStatesHandler(
+ EntityType entityType, EntityInstance entityInstance,
+ StateSetId stateSetId, CompositeCount compEffecterCnt,
+ const std::vector<set_effecter_state_field>& stateField)
+{
+ int rc = PLDM_SUCCESS;
+
+ for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
+ {
+ if (stateField[currState].set_request == PLDM_REQUEST_SET)
+ {
+ if (entityType == PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER &&
+ stateSetId == PLDM_OEM_IBM_BOOT_STATE)
+ {
+ rc = setBootSide(entityInstance, currState, stateField,
+ codeUpdate);
+ }
+ else
+ {
+ rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
+ }
+ }
+ if (rc != PLDM_SUCCESS)
+ {
+ break;
+ }
+ }
+ return rc;
+}
+
+void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
+ pldm::responder::platform::Handler* handler)
+{
+ platformHandler = handler;
+}
+
+} // namespace oem_ibm_platform
+
+} // namespace responder
+
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
new file mode 100644
index 0000000..2d294f0
--- /dev/null
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "inband_code_update.hpp"
+#include "libpldmresponder/oem_handler.hpp"
+#include "libpldmresponder/platform.hpp"
+
+namespace pldm
+{
+
+namespace responder
+{
+
+namespace oem_ibm_platform
+{
+
+#define PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE 32768
+#define PLDM_OEM_IBM_BOOT_STATE 32769
+
+class Handler : public oem_platform::Handler
+{
+ public:
+ Handler(const pldm::utils::DBusHandler* dBusIntf,
+ pldm::responder::CodeUpdate* codeUpdate) :
+ oem_platform::Handler(dBusIntf),
+ codeUpdate(codeUpdate), platformHandler(nullptr)
+ {
+ codeUpdate->setVersions();
+ }
+
+ int getOemStateSensorReadingsHandler(
+ EntityType entityType, EntityInstance entityInstance,
+ StateSetId stateSetId, CompositeCount compSensorCnt,
+ std::vector<get_sensor_state_field>& stateField);
+
+ int oemSetStateEffecterStatesHandler(
+ EntityType entityType, EntityInstance entityInstance,
+ StateSetId stateSetId, CompositeCount compEffecterCnt,
+ const std::vector<set_effecter_state_field>& stateField);
+
+ /** @brief Method to set the platform handler in the
+ * oem_ibm_handler class
+ * @param[in] handler - pointer to PLDM platform handler
+ */
+ void setPlatformHandler(pldm::responder::platform::Handler* handler);
+
+ ~Handler() = default;
+
+ pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
+ pldm::responder::platform::Handler*
+ platformHandler; //!< pointer to PLDM platform handler
+};
+
+} // namespace oem_ibm_platform
+
+} // namespace responder
+
+} // namespace pldm
diff --git a/oem/ibm/test/libpldmresponder_fileio_test.cpp b/oem/ibm/test/libpldmresponder_fileio_test.cpp
index e425a9a..65998a7 100644
--- a/oem/ibm/test/libpldmresponder_fileio_test.cpp
+++ b/oem/ibm/test/libpldmresponder_fileio_test.cpp
@@ -222,7 +222,8 @@
&address, sizeof(address));
// Pass invalid payload length
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileIntoMemory(request, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -252,7 +253,8 @@
// Initialise the file table with 2 valid file handles 0 & 1.
auto& table = buildFileTable(fileTableConfig.c_str());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -283,7 +285,8 @@
using namespace pldm::filetable;
auto& table = buildFileTable(fileTableConfig.c_str());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
@@ -314,7 +317,8 @@
using namespace pldm::filetable;
auto& table = buildFileTable(fileTableConfig.c_str());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -348,7 +352,8 @@
using namespace pldm::filetable;
auto& table = buildFileTable(fileTableConfig.c_str());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileIntoMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -376,7 +381,8 @@
&address, sizeof(address));
// Pass invalid payload length
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.writeFileFromMemory(request, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -411,7 +417,8 @@
// Initialise the file table with 2 valid file handles 0 & 1.
auto& table = buildFileTable(fileTableConfig.c_str());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.writeFileFromMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -443,7 +450,8 @@
// Initialise the file table with 2 valid file handles 0 & 1.
auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.writeFileFromMemory(request, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
@@ -512,7 +520,8 @@
request->operation_flag = opFlag;
request->table_type = type;
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -535,7 +544,8 @@
auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
// Pass invalid command payload length
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.getFileTable(request, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -557,7 +567,8 @@
request->operation_flag = opFlag;
request->table_type = type;
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
@@ -585,7 +596,8 @@
auto& table = buildFileTable(fileTableConfig.c_str());
// Invalid payload length
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFile(requestMsgPtr, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -635,7 +647,8 @@
std::vector<char> buffer(length);
stream.read(buffer.data(), length);
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
auto response = reinterpret_cast<pldm_read_file_resp*>(
responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -685,7 +698,8 @@
request->length = length;
// Invalid payload length
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.writeFile(requestMsgPtr, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -732,7 +746,8 @@
request->length = length;
memcpy(request->file_data, fileData.data(), fileData.size());
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
auto response = reinterpret_cast<pldm_read_file_resp*>(
responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -765,7 +780,8 @@
request->length = 17;
request->address = 0;
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.writeFileByTypeFromMemory(req, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
@@ -833,7 +849,8 @@
request->length = 17;
request->address = 0;
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileByTypeIntoMemory(req, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
struct pldm_read_write_file_by_type_memory_resp* resp =
@@ -871,7 +888,8 @@
request->offset = 0;
request->length = 13;
- oem_ibm::Handler handler;
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+ oem_ibm::Handler handler(oemPlatformHandler.get());
auto response = handler.readFileByType(req, 0);
auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
struct pldm_read_write_file_by_type_resp* resp =
diff --git a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
new file mode 100644
index 0000000..6b837dd
--- /dev/null
+++ b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
@@ -0,0 +1,103 @@
+#include "libpldm/entity.h"
+
+#include "common/utils.hpp"
+#include "libpldmresponder/event_parser.hpp"
+#include "libpldmresponder/pdr.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
+#include "libpldmresponder/platform.hpp"
+#include "oem/ibm/libpldmresponder/inband_code_update.hpp"
+#include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"
+#include "test/mocked_utils.hpp"
+
+#include <iostream>
+
+using namespace pldm::utils;
+using namespace pldm::responder;
+using namespace pldm::responder::pdr;
+using namespace pldm::responder::pdr_utils;
+using namespace pldm::responder::oem_ibm_platform;
+
+class MockCodeUpdate : public CodeUpdate
+{
+ public:
+ MockCodeUpdate(const pldm::utils::DBusHandler* dBusIntf) :
+ CodeUpdate(dBusIntf)
+ {}
+
+ MOCK_METHOD(void, setVersions, (), (override));
+};
+
+TEST(oemSetStateEffecterStatesHandler, testGoodRequest)
+{
+ uint16_t entityID_ = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+ uint16_t stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
+ uint16_t entityInstance_ = 0;
+ uint8_t compSensorCnt_ = 1;
+
+ std::vector<get_sensor_state_field> stateField;
+
+ auto mockDbusHandler = std::make_unique<MockdBusHandler>();
+ std::unique_ptr<CodeUpdate> mockCodeUpdate =
+ std::make_unique<MockCodeUpdate>(mockDbusHandler.get());
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+
+ oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
+ mockDbusHandler.get(), mockCodeUpdate.get());
+
+ auto rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField);
+
+ ASSERT_EQ(rc, PLDM_SUCCESS);
+ ASSERT_EQ(stateField.size(), 1);
+ ASSERT_EQ(stateField[0].event_state, tSideNum);
+ ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_ENABLED);
+ ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_UNKNOWN);
+ ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN);
+
+ entityInstance_ = 1;
+
+ std::vector<get_sensor_state_field> stateField1;
+ rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+ ASSERT_EQ(stateField1.size(), 1);
+ ASSERT_EQ(stateField1[0].event_state, tSideNum);
+
+ entityInstance_ = 2;
+ rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+ ASSERT_EQ(stateField1[0].event_state, PLDM_SENSOR_UNKNOWN);
+
+ entityID_ = 40;
+ stateSetId_ = 50;
+ rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField1);
+ ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
+
+ entityID_ = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
+ entityInstance_ = 0;
+ stateSetId_ = PLDM_OEM_IBM_BOOT_STATE;
+ compSensorCnt_ = 1;
+
+ std::vector<set_effecter_state_field> setEffecterStateField;
+ setEffecterStateField.push_back({PLDM_REQUEST_SET, pSideNum});
+
+ rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_,
+ setEffecterStateField);
+ ASSERT_EQ(rc, PLDM_SUCCESS);
+
+ entityInstance_ = 2;
+ rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_,
+ setEffecterStateField);
+
+ ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
+
+ entityID_ = 34;
+ stateSetId_ = 99;
+ entityInstance_ = 0;
+ rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
+ entityID_, entityInstance_, stateSetId_, compSensorCnt_,
+ setEffecterStateField);
+ ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
+}
diff --git a/pldmd/pldmd.cpp b/pldmd/pldmd.cpp
index c99ab18..7bf2aa4 100644
--- a/pldmd/pldmd.cpp
+++ b/pldmd/pldmd.cpp
@@ -13,6 +13,7 @@
#include "libpldmresponder/base.hpp"
#include "libpldmresponder/bios.hpp"
#include "libpldmresponder/fru.hpp"
+#include "libpldmresponder/oem_handler.hpp"
#include "libpldmresponder/platform.hpp"
#include "xyz/openbmc_project/PLDM/Event/server.hpp"
@@ -42,6 +43,7 @@
#ifdef OEM_IBM
#include "libpldmresponder/file_io.hpp"
+#include "libpldmresponder/oem_ibm_handler.hpp"
#endif
constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1;
@@ -193,6 +195,18 @@
}
Invoker invoker{};
+ std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
+
+#ifdef OEM_IBM
+ std::unique_ptr<pldm::responder::CodeUpdate> codeUpdate =
+ std::make_unique<pldm::responder::CodeUpdate>(dbusHandler.get());
+ oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
+ dbusHandler.get(), codeUpdate.get());
+
+ codeUpdate->setOemPlatformHandler(oemPlatformHandler.get());
+ invoker.registerHandler(
+ PLDM_OEM, std::make_unique<oem_ibm::Handler>(oemPlatformHandler.get()));
+#endif
invoker.registerHandler(PLDM_BASE, std::make_unique<base::Handler>());
invoker.registerHandler(PLDM_BIOS, std::make_unique<bios::Handler>(
sockfd, hostEID, &dbusImplReq));
@@ -201,17 +215,20 @@
// FRU table is built lazily when a FRU command or Get PDR command is
// handled. To enable building FRU table, the FRU handler is passed to the
// Platform handler.
- invoker.registerHandler(
- PLDM_PLATFORM, std::make_unique<platform::Handler>(
- dbusHandler.get(), PDR_JSONS_DIR, pdrRepo.get(),
- hostPDRHandler.get(), dbusToPLDMEventHandler.get(),
- fruHandler.get(), true));
- invoker.registerHandler(PLDM_FRU, std::move(fruHandler));
-
+ auto platformHandler = std::make_unique<platform::Handler>(
+ dbusHandler.get(), PDR_JSONS_DIR, pdrRepo.get(), hostPDRHandler.get(),
+ dbusToPLDMEventHandler.get(), fruHandler.get(),
+ oemPlatformHandler.get(), true);
#ifdef OEM_IBM
- invoker.registerHandler(PLDM_OEM, std::make_unique<oem_ibm::Handler>());
+ pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
+ dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
+ oemPlatformHandler.get());
+ oemIbmPlatformHandler->setPlatformHandler(platformHandler.get());
#endif
+ invoker.registerHandler(PLDM_PLATFORM, std::move(platformHandler));
+ invoker.registerHandler(PLDM_FRU, std::move(fruHandler));
+
pldm::utils::CustomFD socketFd(sockfd);
struct sockaddr_un addr
diff --git a/test/libpldmresponder_pdr_effecter_test.cpp b/test/libpldmresponder_pdr_effecter_test.cpp
index 77f59a5..0b91ee8 100644
--- a/test/libpldmresponder_pdr_effecter_test.cpp
+++ b/test/libpldmresponder_pdr_effecter_test.cpp
@@ -28,7 +28,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
@@ -127,7 +127,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_NUMERIC_EFFECTER_PDR);
@@ -173,7 +173,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
@@ -194,7 +194,7 @@
auto inPDRRepo = pldm_pdr_init();
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
uint16_t entityType = 33;
uint16_t entityInstance = 0;
uint16_t containerId = 0;
diff --git a/test/libpldmresponder_pdr_sensor_test.cpp b/test/libpldmresponder_pdr_sensor_test.cpp
index 6429fc6..ad844c1 100644
--- a/test/libpldmresponder_pdr_sensor_test.cpp
+++ b/test/libpldmresponder_pdr_sensor_test.cpp
@@ -33,7 +33,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
handler.getPDR(req, requestPayloadLength);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR);
@@ -83,7 +83,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
handler.getPDR(req, requestPayloadLength);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR);
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
index 71fec26..0e6164b 100644
--- a/test/libpldmresponder_platform_test.cpp
+++ b/test/libpldmresponder_platform_test.cpp
@@ -40,7 +40,7 @@
auto pdrRepo = pldm_pdr_init();
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo repo(pdrRepo);
ASSERT_EQ(repo.empty(), false);
auto response = handler.getPDR(req, requestPayloadLength);
@@ -77,7 +77,7 @@
auto pdrRepo = pldm_pdr_init();
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo repo(pdrRepo);
ASSERT_EQ(repo.empty(), false);
auto response = handler.getPDR(req, requestPayloadLength);
@@ -108,7 +108,7 @@
auto pdrRepo = pldm_pdr_init();
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo repo(pdrRepo);
ASSERT_EQ(repo.empty(), false);
auto response = handler.getPDR(req, requestPayloadLength);
@@ -137,7 +137,7 @@
auto pdrRepo = pldm_pdr_init();
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo repo(pdrRepo);
ASSERT_EQ(repo.empty(), false);
auto response = handler.getPDR(req, requestPayloadLength);
@@ -168,7 +168,7 @@
auto pdrRepo = pldm_pdr_init();
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo repo(pdrRepo);
ASSERT_EQ(repo.empty(), false);
auto response = handler.getPDR(req, requestPayloadLength);
@@ -230,7 +230,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
handler.getPDR(req, requestPayloadLength);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
@@ -276,7 +276,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
handler.getPDR(req, requestPayloadLength);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
@@ -321,7 +321,7 @@
auto numericEffecterPdrRepo = pldm_pdr_init();
Repo numericEffecterPDRs(numericEffecterPdrRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR);
@@ -363,7 +363,7 @@
auto numericEffecterPdrRepo = pldm_pdr_init();
Repo numericEffecterPDRs(numericEffecterPdrRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR);
@@ -535,7 +535,8 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
MockdBusHandler mockedUtils;
- Handler handler(&mockedUtils, "", inPDRRepo, nullptr, nullptr, nullptr);
+ Handler handler(&mockedUtils, "", inPDRRepo, nullptr, nullptr, nullptr,
+ nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_TERMINUS_LOCATOR_PDR);
@@ -579,7 +580,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR);
pdr_utils::PdrEntry e;
@@ -625,7 +626,7 @@
auto outPDRRepo = pldm_pdr_init();
Repo outRepo(outPDRRepo);
Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr);
Repo inRepo(inPDRRepo);
getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR);
pdr_utils::PdrEntry e;
diff --git a/test/meson.build b/test/meson.build
index fd1a2ec..43de609 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -42,7 +42,8 @@
if get_option('oem-ibm').enabled()
tests += [
- '../oem/ibm/test/libpldmresponder_fileio_test'
+ '../oem/ibm/test/libpldmresponder_fileio_test',
+ '../oem/ibm/test/libpldmresponder_oem_platform_test'
]
endif