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/src/gpio.cpp b/src/gpio.cpp
index 0538800..1caae54 100644
--- a/src/gpio.cpp
+++ b/src/gpio.cpp
@@ -83,14 +83,14 @@
return getGpioBase() + offset;
}
-int configGroupGpio(sdbusplus::bus::bus& bus, buttonConfig& buttonIFConfig)
+int configGroupGpio(buttonConfig& buttonIFConfig)
{
int result = 0;
// iterate the list of gpios from the button interface config
// and initialize them
for (auto& gpioCfg : buttonIFConfig.gpios)
{
- result = configGpio(bus, gpioCfg);
+ result = configGpio(gpioCfg);
if (result < 0)
{
@@ -107,7 +107,7 @@
return result;
}
-int configGpio(sdbusplus::bus::bus& bus, gpioInfo& gpioConfig)
+int configGpio(gpioInfo& gpioConfig)
{
auto gpioNum = gpioConfig.number;
diff --git a/src/id_button.cpp b/src/id_button.cpp
index c543556..71e8539 100644
--- a/src/id_button.cpp
+++ b/src/id_button.cpp
@@ -16,7 +16,47 @@
#include "id_button.hpp"
+// add the button iface class to registry
+static ButtonIFRegister<IDButton> buttonRegister;
+
void IDButton::simPress()
{
pressed();
-}
\ No newline at end of file
+}
+
+void IDButton::handleEvent(sd_event_source* es, int fd, uint32_t revents)
+{
+ int n = -1;
+ char buf = '0';
+ n = ::lseek(fd, 0, SEEK_SET);
+
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ (getFormFactorType() + " : lseek error!").c_str());
+ return;
+ }
+
+ n = ::read(fd, &buf, sizeof(buf));
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ (getFormFactorType() + " : read error!").c_str());
+ return;
+ }
+
+ if (buf == '0')
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ (getFormFactorType() + " : pressed").c_str());
+ // emit pressed signal
+ pressed();
+ }
+ else
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ (getFormFactorType() + " : released").c_str());
+ // released
+ released();
+ }
+}
diff --git a/src/main.cpp b/src/main.cpp
index ca7fbaa..a99c603 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -14,14 +14,12 @@
// limitations under the License.
*/
+#include "button_factory.hpp"
#include "gpio.hpp"
-#include "id_button.hpp"
-#include "power_button.hpp"
-#include "reset_button.hpp"
#include <fstream>
#include <nlohmann/json.hpp>
-
+#include <phosphor-logging/elog-errors.hpp>
static constexpr auto gpioDefFile = "/etc/default/obmc/gpio/gpio_defs.json";
int main(int argc, char* argv[])
@@ -29,7 +27,7 @@
int ret = 0;
phosphor::logging::log<phosphor::logging::level::INFO>(
- "Start power button service...");
+ "Start Phosphor buttons service...");
sd_event* event = nullptr;
ret = sd_event_default(&event);
@@ -47,6 +45,8 @@
bus, "/xyz/openbmc_project/Chassis/Buttons"};
bus.request_name("xyz.openbmc_project.Chassis.Buttons");
+ //
+ std::vector<std::unique_ptr<ButtonIface>> buttonInterfaces;
std::ifstream gpios{gpioDefFile};
auto json = nlohmann::json::parse(gpios, nullptr, true);
@@ -54,9 +54,6 @@
// load gpio config from gpio defs json file and create button interface
// objects based on the button form factor type
- std::unique_ptr<PowerButton> pb;
- std::unique_ptr<ResetButton> rb;
- std::unique_ptr<IDButton> ib;
for (auto groupGpioConfig : gpioDefs)
{
@@ -72,23 +69,9 @@
buttonCfg.formFactorName = formFactorName;
buttonCfg.gpios.push_back(gpioCfg);
}
- if (buttonCfg.formFactorName == PowerButton::getGpioName())
- {
- pb = std::make_unique<PowerButton>(bus, POWER_DBUS_OBJECT_NAME,
- eventP, buttonCfg);
- }
- if (buttonCfg.formFactorName == ResetButton::getGpioName())
- {
- rb = std::make_unique<ResetButton>(bus, RESET_DBUS_OBJECT_NAME,
- eventP, buttonCfg);
- }
-
- if (buttonCfg.formFactorName == IDButton::getGpioName())
- {
- ib = std::make_unique<IDButton>(bus, ID_DBUS_OBJECT_NAME, eventP,
- buttonCfg);
- }
+ buttonInterfaces.emplace_back(ButtonFactory::instance().createInstance(
+ formFactorName, bus, eventP, buttonCfg));
}
try
diff --git a/src/power_button.cpp b/src/power_button.cpp
index feadeee..2e69154 100644
--- a/src/power_button.cpp
+++ b/src/power_button.cpp
@@ -16,6 +16,9 @@
#include "power_button.hpp"
+// add the button iface class to registry
+static ButtonIFRegister<PowerButton> buttonRegister;
+
void PowerButton::simPress()
{
pressed();
@@ -25,3 +28,66 @@
{
pressedLong();
}
+
+void PowerButton::updatePressedTime()
+{
+ pressedTime = std::chrono::steady_clock::now();
+}
+
+auto PowerButton::getPressTime() const
+{
+ return pressedTime;
+}
+
+void PowerButton::handleEvent(sd_event_source* es, int fd, uint32_t revents)
+{
+
+ int n = -1;
+ char buf = '0';
+
+ n = ::lseek(fd, 0, SEEK_SET);
+
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "POWER_BUTTON: lseek error!");
+ return;
+ }
+
+ n = ::read(fd, &buf, sizeof(buf));
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "POWER_BUTTON: read error!");
+ return;
+ }
+
+ if (buf == '0')
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "POWER_BUTTON: pressed");
+
+ updatePressedTime();
+ // emit pressed signal
+ pressed();
+ }
+ else
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "POWER_BUTTON: released");
+
+ auto now = std::chrono::steady_clock::now();
+ auto d = std::chrono::duration_cast<std::chrono::milliseconds>(
+ now - getPressTime());
+
+ if (d > std::chrono::milliseconds(LONG_PRESS_TIME_MS))
+ {
+ pressedLong();
+ }
+ else
+ {
+ // released
+ released();
+ }
+ }
+}
diff --git a/src/reset_button.cpp b/src/reset_button.cpp
index 31e01e1..c3e467e 100644
--- a/src/reset_button.cpp
+++ b/src/reset_button.cpp
@@ -18,7 +18,51 @@
#include "xyz/openbmc_project/Chassis/Buttons/Reset/server.hpp"
+// add the button iface class to registry
+static ButtonIFRegister<ResetButton> buttonRegister;
+
void ResetButton::simPress()
{
pressed();
}
+
+void ResetButton::handleEvent(sd_event_source* es, int fd, uint32_t revents)
+{
+ int n = -1;
+ char buf = '0';
+
+ n = ::lseek(fd, 0, SEEK_SET);
+
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "RESET_BUTTON: lseek error!");
+
+ return;
+ }
+
+ n = ::read(fd, &buf, sizeof(buf));
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "RESET_BUTTON: read error!");
+ return;
+ }
+
+ if (buf == '0')
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "RESET_BUTTON: pressed");
+ // emit pressed signal
+ pressed();
+ }
+ else
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "RESET_BUTTON: released");
+ // released
+ released();
+ }
+
+ return;
+}