Add abstract factory to create button iface objects
A abstract factory class is implemented to return
the instance of button interface class based on the
button iface formfactor name provided as
parameter to the abstract factory createInstance
method.
Signed-off-by: Naveen Moses <naveen.mosess@hcl.com>
Change-Id: Ia791a2b6f52d09dd87da0e50a709fc72ac9d1bd7
diff --git a/inc/button_interface.hpp b/inc/button_interface.hpp
new file mode 100644
index 0000000..8648797
--- /dev/null
+++ b/inc/button_interface.hpp
@@ -0,0 +1,118 @@
+#pragma once
+
+#include "common.hpp"
+#include "gpio.hpp"
+#include "xyz/openbmc_project/Chassis/Common/error.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+// This is the base class for all the button interface types
+//
+class ButtonIface
+{
+
+ public:
+ ButtonIface(sdbusplus::bus::bus& bus, EventPtr& event,
+ buttonConfig& buttonCfg,
+ sd_event_io_handler_t handler = ButtonIface::EventHandler) :
+ bus(bus),
+ event(event), config(buttonCfg), callbackHandler(handler)
+ {
+ int ret = -1;
+
+ // config group gpio based on the gpio defs read from the json file
+ ret = configGroupGpio(config);
+
+ if (ret < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ (getFormFactorType() + " : failed to config GPIO").c_str());
+ throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+ IOError();
+ }
+ }
+ virtual ~ButtonIface()
+ {
+ }
+
+ /**
+ * @brief This method is called from sd-event provided callback function
+ * callbackHandler if platform specific event handling is needed then a
+ * derived class instance with its specific evend handling logic along with
+ * init() function can be created to override the default event handling.
+ */
+
+ virtual void handleEvent(sd_event_source* es, int fd, uint32_t revents) = 0;
+ static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
+ void* userdata)
+ {
+ if (userdata)
+ {
+
+ ButtonIface* buttonIface = static_cast<ButtonIface*>(userdata);
+ buttonIface->handleEvent(es, fd, revents);
+ return 0;
+ }
+ }
+
+ std::string getFormFactorType() const
+ {
+ return config.formFactorName;
+ }
+
+ protected:
+ /**
+ * @brief oem specific initialization can be done under init function.
+ * if platform specific initialization is needed then
+ * a derived class instance with its own init function to override the
+ * default init() method can be added.
+ */
+
+ virtual void init()
+ {
+
+ // initialize the button io fd from the buttonConfig
+ // which has fd stored when configGroupGpio is called
+ for (auto gpioCfg : config.gpios)
+ {
+ char buf;
+ int fd = gpioCfg.fd;
+
+ int ret = ::read(fd, &buf, sizeof(buf));
+ if (ret < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ (getFormFactorType() + " : read error!").c_str());
+ }
+
+ ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
+ callbackHandler, this);
+ if (ret < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ (getFormFactorType() + " : failed to add to event loop")
+ .c_str());
+ ::closeGpio(fd);
+ throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+ IOError();
+ }
+ }
+ }
+ /**
+ * @brief similar to init() oem specific deinitialization can be done under
+ * deInit function. if platform specific deinitialization is needed then a
+ * derived class instance with its own init function to override the default
+ * deinit() method can be added.
+ */
+ virtual void deInit()
+ {
+ for (auto gpioCfg : config.gpios)
+ {
+ ::closeGpio(gpioCfg.fd);
+ }
+ }
+
+ buttonConfig config;
+ sdbusplus::bus::bus& bus;
+ EventPtr& event;
+ sd_event_io_handler_t callbackHandler;
+};