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/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