1 /** 2 * Copyright © 2017 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 "evdevpp/evdev.hpp" 19 // TODO https://github.com/openbmc/phosphor-fan-presence/issues/22 20 // #include "sdevent/event.hpp" 21 // #include "sdevent/io.hpp" 22 #include "utility.hpp" 23 24 #include <algorithm> 25 #include <cassert> 26 #include <iostream> 27 #include <iterator> 28 #include <memory> 29 30 namespace phosphor 31 { 32 namespace fan 33 { 34 namespace util 35 { 36 37 ArgumentParser::ArgumentParser(int argc, char** argv) 38 { 39 auto option = 0; 40 while (-1 != (option = getopt_long(argc, argv, optionstr, options, NULL))) 41 { 42 if ((option == '?') || (option == 'h')) 43 { 44 usage(argv); 45 exit(1); 46 } 47 48 auto i = &options[0]; 49 while ((i->val != option) && (i->val != 0)) 50 { 51 ++i; 52 } 53 54 if (i->val) 55 { 56 arguments[i->name] = (i->has_arg ? optarg : true_string); 57 } 58 } 59 } 60 61 const std::string& ArgumentParser::operator[](const std::string& opt) 62 { 63 auto i = arguments.find(opt); 64 if (i == arguments.end()) 65 { 66 return empty_string; 67 } 68 else 69 { 70 return i->second; 71 } 72 } 73 74 void ArgumentParser::usage(char** argv) 75 { 76 std::cerr << "Usage: " << argv[0] << " [options]\n"; 77 std::cerr << "Options:\n"; 78 std::cerr << " --path evdev devpath\n"; 79 std::cerr << " --type evdev type\n"; 80 std::cerr << " --code evdev code\n"; 81 std::cerr << std::flush; 82 } 83 84 const option ArgumentParser::options[] = { 85 {"path", required_argument, NULL, 'p'}, 86 {"type", required_argument, NULL, 't'}, 87 {"code", required_argument, NULL, 'c'}, 88 {0, 0, 0, 0}, 89 }; 90 91 const char* ArgumentParser::optionstr = "p:t:c:"; 92 93 const std::string ArgumentParser::true_string = "true"; 94 const std::string ArgumentParser::empty_string = ""; 95 96 static void exit_with_error(const char* err, char** argv) 97 { 98 ArgumentParser::usage(argv); 99 std::cerr << "\n"; 100 std::cerr << "ERROR: " << err << "\n"; 101 exit(1); 102 } 103 104 } // namespace util 105 } // namespace fan 106 } // namespace phosphor 107 108 int main(int argc, char* argv[]) 109 { 110 using namespace phosphor::fan::util; 111 112 auto options = std::make_unique<ArgumentParser>(argc, argv); 113 auto path = (*options)["path"]; 114 auto stype = (*options)["type"]; 115 auto scode = (*options)["code"]; 116 unsigned int type = EV_KEY; 117 118 if (path == ArgumentParser::empty_string) 119 { 120 exit_with_error("Path not specified or invalid.", argv); 121 } 122 if (stype != ArgumentParser::empty_string) 123 { 124 type = stoul(stype); 125 } 126 127 if (scode == ArgumentParser::empty_string) 128 { 129 exit_with_error("Keycode not specified or invalid.", argv); 130 } 131 options.reset(); 132 133 // TODO https://github.com/openbmc/phosphor-fan-presence/issues/22 134 // auto loop = sdevent::event::newDefault(); 135 phosphor::fan::util::FileDescriptor fd( 136 open(path.c_str(), O_RDONLY | O_NONBLOCK)); 137 auto evdev = evdevpp::evdev::newFromFD(fd()); 138 // sdevent::event::io::IO callback(loop, fd(), [&evdev](auto& s) { 139 // unsigned int type, code, value; 140 // std::tie(type, code, value) = evdev.next(); 141 // std::cout << "type: " << libevdev_event_type_get_name(type) 142 // << " code: " << libevdev_event_code_get_name(type, code) 143 // << " value: " << value << "\n"; 144 // }); 145 146 auto value = evdev.fetch(type, stoul(scode)); 147 std::cout << "type: " << libevdev_event_type_get_name(type) 148 << " code: " << libevdev_event_code_get_name(type, stoul(scode)) 149 << " value: " << value << "\n"; 150 151 // loop.loop(); 152 153 return 0; 154 } 155