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 "argument.hpp" 18 #include "monitor.hpp" 19 20 #include <systemd/sd-event.h> 21 22 #include <phosphor-logging/log.hpp> 23 24 #include <iostream> 25 #include <string> 26 27 using namespace phosphor::logging; 28 static void exitWithError(const char* err, char** argv) 29 { 30 phosphor::gpio::ArgumentParser::usage(argv); 31 std::cerr << "ERROR: " << err << "\n"; 32 exit(EXIT_FAILURE); 33 } 34 35 int main(int argc, char** argv) 36 { 37 // Read arguments. 38 auto options = phosphor::gpio::ArgumentParser(argc, argv); 39 40 // Parse out path argument. 41 auto path = (options)["path"]; 42 if (path == phosphor::gpio::ArgumentParser::emptyString) 43 { 44 exitWithError("path not specified.", argv); 45 } 46 47 // Parse out key number that we are interested in 48 // Its integer mapping to the GPIO key configured by the kernel 49 auto key = (options)["key"]; 50 if (key == phosphor::gpio::ArgumentParser::emptyString) 51 { 52 exitWithError("Key not specified.", argv); 53 } 54 55 // Parse out assertion polarity interested in 56 // Its either 1 or 0 for press / release 57 auto polarity = (options)["polarity"]; 58 if (polarity == phosphor::gpio::ArgumentParser::emptyString) 59 { 60 exitWithError("Polarity not specified.", argv); 61 } 62 63 // Parse out target argument. It is fine if the caller does not 64 // pass this if they are not interested in calling into any target 65 // on meeting a condition. 66 auto target = (options)["target"]; 67 68 bool continueRun = 69 (options["continue"] == phosphor::gpio::ArgumentParser::trueString); 70 71 sd_event* event = nullptr; 72 auto r = sd_event_default(&event); 73 if (r < 0) 74 { 75 log<level::ERR>("Error creating a default sd_event handler"); 76 return r; 77 } 78 phosphor::gpio::EventPtr eventP{event}; 79 event = nullptr; 80 81 // Create a monitor object and let it do all the rest 82 phosphor::gpio::Monitor monitor(path, std::stoi(key), std::stoi(polarity), 83 target, eventP, continueRun); 84 85 // Wait for client requests until this application has processed 86 // at least one expected GPIO state change 87 while (!monitor.completed()) 88 { 89 // -1 denotes wait for ever 90 r = sd_event_run(eventP.get(), (uint64_t)-1); 91 if (r < 0) 92 { 93 log<level::ERR>("Failure in processing request", 94 entry("ERROR=%s", strerror(-r))); 95 break; 96 } 97 } 98 99 return 0; 100 } 101