1 /** 2 * Copyright © 2016 IBM Corporation 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 "monitor.hpp" 18 19 #include <fcntl.h> 20 21 #include <phosphor-logging/log.hpp> 22 23 namespace phosphor 24 { 25 namespace gpio 26 { 27 28 // systemd service to kick start a target. 29 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 30 constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; 31 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 32 33 using namespace phosphor::logging; 34 35 // Callback handler when there is an activity on the FD 36 int Monitor::processEvents(sd_event_source* es, int fd, uint32_t revents, 37 void* userData) 38 { 39 log<level::INFO>("GPIO line altered"); 40 auto monitor = static_cast<Monitor*>(userData); 41 42 monitor->analyzeEvent(); 43 return 0; 44 } 45 46 // Analyzes the GPIO event 47 void Monitor::analyzeEvent() 48 { 49 // Data returned 50 struct input_event ev 51 { 52 }; 53 int rc = 0; 54 55 // While testing, observed that not having a loop here was leading 56 // into events being missed. 57 while (rc >= 0) 58 { 59 // Wait until no more events are available on the device. 60 rc = libevdev_next_event(devicePtr.get(), LIBEVDEV_READ_FLAG_NORMAL, 61 &ev); 62 if (rc < 0) 63 { 64 // There was an error waiting for events, mostly that there are no 65 // events to be read.. So continue waiting... 66 return; 67 }; 68 69 if (rc == LIBEVDEV_READ_STATUS_SUCCESS) 70 { 71 if (ev.type == EV_SYN && ev.code == SYN_REPORT) 72 { 73 continue; 74 } 75 else if (ev.code == key && ev.value == polarity) 76 { 77 // If the code/value is what we are interested in, declare done. 78 // User supplied systemd unit 79 if (!target.empty()) 80 { 81 auto bus = sdbusplus::bus::new_default(); 82 auto method = 83 bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, 84 SYSTEMD_INTERFACE, "StartUnit"); 85 method.append(target); 86 method.append("replace"); 87 88 bus.call_noreply(method); 89 } 90 91 if (!continueAfterKeyPress) 92 { 93 // This marks the completion of handling the gpio assertion 94 // and the app can exit 95 complete = true; 96 } 97 return; 98 } 99 } 100 }; 101 102 return; 103 } 104 105 } // namespace gpio 106 } // namespace phosphor 107