pldmd: D-Bus to host effecter translation
This commit implements a mechanism to move the Host's boot state
from 'not started' to 'boot complete' by setting the relevant
Host effecter when the associated D-Bus property is set in the BMC.
Also added an example JSON to match D-Bus to host effecters
Change-Id: I41025d99d2b4b3452d4c51b03efe3750e159328b
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/dbus_to_host_effecters.hpp b/dbus_to_host_effecters.hpp
new file mode 100644
index 0000000..7c37c88
--- /dev/null
+++ b/dbus_to_host_effecters.hpp
@@ -0,0 +1,182 @@
+#pragma once
+
+#include "dbus_impl_requester.hpp"
+#include "types.hpp"
+#include "utils.hpp"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace pldm
+{
+
+using namespace utils;
+using namespace dbus_api;
+
+namespace host_effecters
+{
+
+using DbusChgHostEffecterProps = std::map<dbus::Property, PropertyValue>;
+
+/** @struct State
+ * Contains the state set id and the possible states for
+ * an effecter
+ */
+struct PossibleState
+{
+ uint16_t stateSetId; //!< State set id
+ std::vector<uint8_t> states; //!< Possible states
+};
+
+/** @struct DBusEffecterMapping
+ * Contains the D-Bus information for an effecter
+ */
+struct DBusEffecterMapping
+{
+ DBusMapping dbusMap;
+ std::vector<PropertyValue> propertyValues; //!< D-Bus property values
+ PossibleState state; //!< Corresponding effecter states
+};
+
+/** @struct EffecterInfo
+ * Contains the effecter information as a whole
+ */
+struct EffecterInfo
+{
+ uint8_t mctpEid; //!< Host mctp eid
+ uint16_t containerId; //!< Container Id for host effecter
+ uint16_t entityType; //!< Entity type for the host effecter
+ uint16_t entityInstance; //!< Entity instance for the host effecter
+ uint8_t compEffecterCnt; //!< Composite effecter count
+ std::vector<DBusEffecterMapping>
+ dbusInfo; //!< D-Bus information for the effecter id
+};
+
+/** @class HostEffecterParser
+ *
+ * @brief This class parses the Host Effecter json file and monitors for the
+ * D-Bus changes for the effecters. Upon change, calls the corresponding
+ * setStateEffecterStates on the host
+ */
+class HostEffecterParser
+{
+ public:
+ HostEffecterParser() = delete;
+ HostEffecterParser(const HostEffecterParser&) = delete;
+ HostEffecterParser& operator=(const HostEffecterParser&) = delete;
+ HostEffecterParser(HostEffecterParser&&) = delete;
+ HostEffecterParser& operator=(HostEffecterParser&&) = delete;
+ virtual ~HostEffecterParser() = default;
+
+ /** @brief Constructor to create a HostEffecterParser object.
+ * @param[in] requester - PLDM Requester object pointer
+ * @param[in] fd - socket fd to communicate to host
+ * @param[in] repo - PLDM PDR repository
+ * @param[in] dbusHandler - D-bus Handler
+ * @param[in] jsonPath - path for the json file
+ * @param[in] verbose - verbosity
+ */
+ explicit HostEffecterParser(Requester* requester, int fd,
+ const pldm_pdr* repo,
+ DBusHandler* const dbusHandler,
+ const std::string& jsonPath,
+ bool verbose = false) :
+ requester(requester),
+ sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), verbose(verbose)
+ {
+ try
+ {
+ parseEffecterJson(jsonPath);
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "The json file does not exist or malformed, ERROR="
+ << e.what() << "\n";
+ }
+ }
+
+ /* @brief Parses the host effecter json
+ *
+ * @param[in] jsonPath - path for the json file
+ */
+ void parseEffecterJson(const std::string& jsonPath);
+
+ /* @brief Method to take action when the subscribed D-Bus property is
+ * changed
+ * @param[in] chProperties - list of properties which have changed
+ * @param[in] effecterInfoIndex - index of effecterInfo pointer in
+ * hostEffecterInfo
+ * @param[in] dbusInfoIndex - index on dbusInfo pointer in each effecterInfo
+ * @param[in] effecterId - host effecter id
+ * @return - none
+ */
+ void processHostEffecterChangeNotification(
+ const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
+ size_t dbusInfoIndex, uint16_t effecterId);
+
+ /* @brief Populate the property values in each dbusInfo from the json
+ *
+ * @param[in] dBusValues - json values
+ * @param[out] propertyValues - dbusInfo property values
+ * @param[in] propertyType - type of the D-Bus property
+ * @return - none
+ */
+ void populatePropVals(const Json& dBusValues,
+ std::vector<PropertyValue>& propertyValues,
+ const std::string& propertyType);
+
+ /* @brief Set a host state effecter
+ *
+ * @param[in] effecterInfoIndex - index of effecterInfo pointer in
+ * hostEffecterInfo
+ * @param[in] stateField - vector of state fields equal to composite
+ * effecter count in number
+ * @param[in] effecterId - host effecter id
+ * @return - PLDM status code
+ */
+ virtual int
+ setHostStateEffecter(size_t effecterInfoIndex,
+ std::vector<set_effecter_state_field>& stateField,
+ uint16_t effecterId);
+
+ /* @brief Fetches the new state value and the index in stateField set which
+ * needs to be set with the new value in the setStateEffecter call
+ * @param[in] effecterInfoIndex - index of effecterInfo in hostEffecterInfo
+ * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
+ * @param[in] propertyValue - the changed D-Bus property value
+ * @return - the new state value
+ */
+ uint8_t findNewStateValue(size_t effecterInfoIndex, size_t dbusInfoIndex,
+ const PropertyValue& propertyValue);
+
+ /* @brief Subscribes for D-Bus property change signal on the specified
+ * object
+ *
+ * @param[in] objectPath - D-Bus object path to look for
+ * @param[in] interface - D-Bus interface
+ * @param[in] effecterInfoIndex - index of effecterInfo pointer in
+ * hostEffecterInfo
+ * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
+ * @param[in] effecterId - host effecter id
+ */
+ virtual void createHostEffecterMatch(const std::string& objectPath,
+ const std::string& interface,
+ size_t effecterInfoIndex,
+ size_t dbusInfoIndex,
+ uint16_t effecterId);
+
+ protected:
+ Requester* requester; //!< Reference to Requester to obtain instance id
+ int sockFd; //!< Socket fd to send message to host
+ const pldm_pdr* pdrRepo; //!< Reference to PDR repo
+ std::vector<EffecterInfo> hostEffecterInfo; //!< Parsed effecter information
+ std::vector<std::unique_ptr<sdbusplus::bus::match::match>>
+ effecterInfoMatch; //!< vector to catch the D-Bus property change
+ //!< signals for the effecters
+ const DBusHandler* dbusHandler; //!< D-bus Handler
+ bool verbose; //!< verbose flag
+};
+
+} // namespace host_effecters
+} // namespace pldm