blob: fcdf8f5a32f22b0be2a7d2ad1eaab41950225447 [file] [log] [blame]
Vijay Khemka939a6432019-10-09 17:45:45 -07001/**
2 * Copyright © 2019 Facebook
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "gpioMon.hpp"
18
19#include <phosphor-logging/log.hpp>
20#include <sdbusplus/bus.hpp>
21
22namespace phosphor
23{
24namespace gpio
25{
26
27/* systemd service to kick start a target. */
28constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
29constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
30constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
31
Delphine CC Chiua66ac0f2023-01-09 17:12:23 +080032constexpr auto falling = "FALLING";
33constexpr auto rising = "RISING";
34
Vijay Khemka939a6432019-10-09 17:45:45 -070035using namespace phosphor::logging;
36
37void GpioMonitor::scheduleEventHandler()
38{
39
40 gpioEventDescriptor.async_wait(
41 boost::asio::posix::stream_descriptor::wait_read,
42 [this](const boost::system::error_code& ec) {
43 if (ec)
44 {
45 std::string msg = gpioLineMsg + "event handler error" +
46 std::string(ec.message());
47 log<level::ERR>(msg.c_str());
48 return;
49 }
50 gpioEventHandler();
51 });
52}
53
54void GpioMonitor::gpioEventHandler()
55{
56 gpiod_line_event gpioLineEvent;
57
58 if (gpiod_line_event_read_fd(gpioEventDescriptor.native_handle(),
59 &gpioLineEvent) < 0)
60 {
61 log<level::ERR>("Failed to read gpioLineEvent from fd",
62 entry("GPIO_LINE=%s", gpioLineMsg.c_str()));
63 return;
64 }
65
66 std::string logMessage =
67 gpioLineMsg + (gpioLineEvent.event_type == GPIOD_LINE_EVENT_RISING_EDGE
68 ? " Asserted"
69 : " Deasserted");
70
71 log<level::INFO>(logMessage.c_str());
72
73 /* Execute the target if it is defined. */
74 if (!target.empty())
75 {
76 auto bus = sdbusplus::bus::new_default();
77 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
78 SYSTEMD_INTERFACE, "StartUnit");
79 method.append(target);
80 method.append("replace");
81
82 bus.call_noreply(method);
83 }
84
Delphine CC Chiua66ac0f2023-01-09 17:12:23 +080085 std::vector<std::string> targetsToStart;
86 if (gpioLineEvent.event_type == GPIOD_LINE_EVENT_RISING_EDGE)
87 {
88 auto risingFind = targets.find(rising);
89 if (risingFind != targets.end())
90 {
91 targetsToStart = risingFind->second;
92 }
93 }
94 else
95 {
96 auto fallingFind = targets.find(falling);
97 if (fallingFind != targets.end())
98 {
99 targetsToStart = fallingFind->second;
100 }
101 }
102
103 /* Execute the multi targets if it is defined. */
104 if (!targetsToStart.empty())
105 {
106 auto bus = sdbusplus::bus::new_default();
107 for (auto& tar : targetsToStart)
108 {
109 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
110 SYSTEMD_INTERFACE, "StartUnit");
111 method.append(tar, "replace");
112 bus.call_noreply(method);
113 }
114 }
115
Vijay Khemka939a6432019-10-09 17:45:45 -0700116 /* if not required to continue monitoring then return */
117 if (!continueAfterEvent)
118 {
119 return;
120 }
121
122 /* Schedule a wait event */
123 scheduleEventHandler();
124}
125
126int GpioMonitor::requestGPIOEvents()
127{
128
129 /* Request an event to monitor for respected gpio line */
130 if (gpiod_line_request(gpioLine, &gpioConfig, 0) < 0)
131 {
132 log<level::ERR>("Failed to request gpioLineEvent",
133 entry("GPIO_LINE=%s", gpioLineMsg.c_str()));
134 return -1;
135 }
136
137 int gpioLineFd = gpiod_line_event_get_fd(gpioLine);
138 if (gpioLineFd < 0)
139 {
140 log<level::ERR>("Failed to get fd for gpioLineEvent",
141 entry("GPIO_LINE=%s", gpioLineMsg.c_str()));
142 return -1;
143 }
144
145 std::string logMsg = gpioLineMsg + " monitoring started";
146 log<level::INFO>(logMsg.c_str());
147
148 /* Assign line fd to descriptor for monitoring */
149 gpioEventDescriptor.assign(gpioLineFd);
150
151 /* Schedule a wait event */
152 scheduleEventHandler();
153
154 return 0;
155}
156} // namespace gpio
157} // namespace phosphor