1 #pragma once 2 3 #include "button_config.hpp" 4 #include "common.hpp" 5 #include "xyz/openbmc_project/Chassis/Common/error.hpp" 6 7 #include <phosphor-logging/elog-errors.hpp> 8 // This is the base class for all the button interface types 9 // 10 class ButtonIface 11 { 12 public: ButtonIface(sdbusplus::bus_t & bus,EventPtr & event,ButtonConfig & buttonCfg,sd_event_io_handler_t handler=ButtonIface::EventHandler)13 ButtonIface(sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg, 14 sd_event_io_handler_t handler = ButtonIface::EventHandler) : 15 bus(bus), event(event), config(buttonCfg), callbackHandler(handler) 16 { 17 int ret = -1; 18 std::string configType; 19 20 // config group gpio or cpld based on the defs read from the json file 21 if (buttonCfg.type == ConfigType::gpio) 22 { 23 configType = "GPIO"; 24 ret = configGroupGpio(config); 25 } 26 else if (buttonCfg.type == ConfigType::cpld) 27 { 28 configType = "CPLD"; 29 ret = configCpld(config); 30 } 31 32 if (ret < 0) 33 { 34 phosphor::logging::log<phosphor::logging::level::ERR>( 35 (getFormFactorType() + " : failed to config " + configType) 36 .c_str()); 37 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 38 IOError(); 39 } 40 } ~ButtonIface()41 virtual ~ButtonIface() {} 42 43 /** 44 * @brief This method is called from sd-event provided callback function 45 * callbackHandler if platform specific event handling is needed then a 46 * derived class instance with its specific evend handling logic along with 47 * init() function can be created to override the default event handling. 48 */ 49 50 virtual void handleEvent(sd_event_source* es, int fd, uint32_t revents) = 0; EventHandler(sd_event_source * es,int fd,uint32_t revents,void * userdata)51 static int EventHandler(sd_event_source* es, int fd, uint32_t revents, 52 void* userdata) 53 { 54 if (userdata) 55 { 56 ButtonIface* buttonIface = static_cast<ButtonIface*>(userdata); 57 buttonIface->handleEvent(es, fd, revents); 58 } 59 60 return 0; 61 } 62 getFormFactorType() const63 std::string getFormFactorType() const 64 { 65 return config.formFactorName; 66 } 67 68 protected: 69 /** 70 * @brief oem specific initialization can be done under init function. 71 * if platform specific initialization is needed then 72 * a derived class instance with its own init function to override the 73 * default init() method can be added. 74 */ 75 init()76 virtual void init() 77 { 78 // initialize the button io fd from the ButtonConfig 79 // which has fd stored when configGroupGpio or configCpld is called 80 for (auto fd : config.fds) 81 { 82 char buf; 83 84 int ret = ::read(fd, &buf, sizeof(buf)); 85 if (ret < 0) 86 { 87 phosphor::logging::log<phosphor::logging::level::ERR>( 88 (getFormFactorType() + " : read error!").c_str()); 89 } 90 91 ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI, 92 callbackHandler, this); 93 if (ret < 0) 94 { 95 phosphor::logging::log<phosphor::logging::level::ERR>( 96 (getFormFactorType() + " : failed to add to event loop") 97 .c_str()); 98 if (fd > 0) 99 { 100 ::close(fd); 101 } 102 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 103 IOError(); 104 } 105 } 106 } 107 /** 108 * @brief similar to init() oem specific deinitialization can be done under 109 * deInit function. if platform specific deinitialization is needed then a 110 * derived class instance with its own init function to override the default 111 * deinit() method can be added. 112 */ deInit()113 virtual void deInit() 114 { 115 for (auto fd : config.fds) 116 { 117 if (fd > 0) 118 { 119 ::close(fd); 120 } 121 } 122 } 123 124 sdbusplus::bus_t& bus; 125 EventPtr& event; 126 ButtonConfig config; 127 sd_event_io_handler_t callbackHandler; 128 }; 129