Add capability of handling GPIO initial values
The edge handling currently allows us to monitor
changes after the service has started. But, a GPIO
could have changed state when the BMC/service is
down and thus potentially missing an error condition.
To address this, two additional keys "INIT_HIGH" and
"INIT_LOW" are added. which will be called at start-up
depending on the current GPIO value.
Tested: Tested on QEMU with a test configuration
and ensured that the systemd units are called
correctly.
Change-Id: I8a6c969b9609080cf0846611831206376fd96c7d
Signed-off-by: Amithash Prasad <amithash@meta.com>
diff --git a/README.md b/README.md
index f66fc1a..b8d9704 100644
--- a/README.md
+++ b/README.md
@@ -41,10 +41,12 @@
triggering event. A journal entry will be added for every event occurs
irrespective of this definition.
7. Targets: This is an optional systemd service which will get started after
- triggering corresponding event(RASING or FALLING). A journal entry will be
- added for every event occurs irrespective of this definition.
+ triggering corresponding event(RISING or FALLING). A journal entry will be
+ added for every event occurs irrespective of this definition. Upon start up,
+ depending on the current GPIO value, the systemd services for INIT_HIGH and
+ INIT_LOW will be called (if defined).
8. Continue: This is a optional flag and if it is defined as true then this gpio
- will be monitored continously. If not defined then monitoring of this gpio
+ will be monitored continuously. If not defined then monitoring of this gpio
will stop after first event.
#### Sample config file
diff --git a/gpioMon.cpp b/gpioMon.cpp
index 3648556..20805cd 100644
--- a/gpioMon.cpp
+++ b/gpioMon.cpp
@@ -31,6 +31,8 @@
constexpr auto falling = "FALLING";
constexpr auto rising = "RISING";
+constexpr auto init_high = "INIT_HIGH";
+constexpr auto init_low = "INIT_LOW";
void GpioMonitor::scheduleEventHandler()
{
@@ -120,6 +122,22 @@
scheduleEventHandler();
}
+void GpioMonitor::gpioHandleInitialState(bool value)
+{
+ if (auto itr = targets.find(value ? init_high : init_low);
+ itr != targets.end())
+ {
+ auto bus = sdbusplus::bus::new_default();
+ for (const auto& tar : itr->second)
+ {
+ auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
+ SYSTEMD_INTERFACE, "StartUnit");
+ method.append(tar, "replace");
+ bus.call_noreply(method);
+ }
+ }
+}
+
int GpioMonitor::requestGPIOEvents()
{
/* Request an event to monitor for respected gpio line */
@@ -136,6 +154,17 @@
return -1;
}
+ int value = gpiod_line_get_value(gpioLine);
+ if (value < 0)
+ {
+ lg2::error("Failed to get value for {GPIO} Error: {ERROR}", "GPIO",
+ gpioLineMsg, "ERROR", strerror(errno));
+ }
+ else
+ {
+ gpioHandleInitialState(value != 0);
+ }
+
lg2::info("{GPIO} monitoring started", "GPIO", gpioLineMsg);
/* Assign line fd to descriptor for monitoring */
diff --git a/gpioMon.hpp b/gpioMon.hpp
index 9f059f0..2add08c 100644
--- a/gpioMon.hpp
+++ b/gpioMon.hpp
@@ -83,6 +83,9 @@
/** @brief Handle the GPIO event and starts configured target */
void gpioEventHandler();
+
+ /** @brief handle current gpio value */
+ void gpioHandleInitialState(bool value);
};
} // namespace gpio