| #pragma once |
| |
| #include "button_config.hpp" |
| #include "common.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_t& bus, EventPtr& event, ButtonConfig& buttonCfg, |
| sd_event_io_handler_t handler = ButtonIface::EventHandler) : |
| bus(bus), event(event), config(buttonCfg), callbackHandler(handler) |
| { |
| int ret = -1; |
| std::string configType; |
| |
| // config group gpio or cpld based on the defs read from the json file |
| if (buttonCfg.type == ConfigType::gpio) |
| { |
| configType = "GPIO"; |
| ret = configGroupGpio(config); |
| } |
| else if (buttonCfg.type == ConfigType::cpld) |
| { |
| configType = "CPLD"; |
| ret = configCpld(config); |
| } |
| |
| if (ret < 0) |
| { |
| phosphor::logging::log<phosphor::logging::level::ERR>( |
| (getFormFactorType() + " : failed to config " + configType) |
| .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 or configCpld is called |
| for (auto fd : config.fds) |
| { |
| char buf; |
| |
| 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()); |
| if (fd > 0) |
| { |
| ::close(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 fd : config.fds) |
| { |
| if (fd > 0) |
| { |
| ::close(fd); |
| } |
| } |
| } |
| |
| sdbusplus::bus_t& bus; |
| EventPtr& event; |
| ButtonConfig config; |
| sd_event_io_handler_t callbackHandler; |
| }; |