blob: dca2c005b4104a9051589fe6dd5d899bcd70fa72 [file] [log] [blame]
Brad Bishopf138c562017-06-15 23:08:09 -04001/**
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
Brad Bishopf138c562017-06-15 23:08:09 -040017#include "argument.hpp"
18#include "evdevpp/evdev.hpp"
19#include "sdevent/event.hpp"
20#include "sdevent/io.hpp"
21#include "utility.hpp"
22
Matthew Barth11fc0a72020-05-26 10:55:54 -050023#include <algorithm>
24#include <cassert>
25#include <iostream>
26#include <iterator>
27#include <memory>
28
Brad Bishopf138c562017-06-15 23:08:09 -040029namespace phosphor
30{
31namespace fan
32{
33namespace util
34{
35
36ArgumentParser::ArgumentParser(int argc, char** argv)
37{
38 auto option = 0;
39 while (-1 != (option = getopt_long(argc, argv, optionstr, options, NULL)))
40 {
41 if ((option == '?') || (option == 'h'))
42 {
43 usage(argv);
William A. Kennington III3e781062018-10-19 17:18:34 -070044 exit(1);
Brad Bishopf138c562017-06-15 23:08:09 -040045 }
46
47 auto i = &options[0];
48 while ((i->val != option) && (i->val != 0))
49 {
50 ++i;
51 }
52
53 if (i->val)
54 {
55 arguments[i->name] = (i->has_arg ? optarg : true_string);
56 }
57 }
58}
59
60const std::string& ArgumentParser::operator[](const std::string& opt)
61{
62 auto i = arguments.find(opt);
63 if (i == arguments.end())
64 {
65 return empty_string;
66 }
67 else
68 {
69 return i->second;
70 }
71}
72
73void ArgumentParser::usage(char** argv)
74{
75 std::cerr << "Usage: " << argv[0] << " [options]\n";
76 std::cerr << "Options:\n";
77 std::cerr << " --path evdev devpath\n";
78 std::cerr << " --type evdev type\n";
79 std::cerr << " --code evdev code\n";
80 std::cerr << std::flush;
81}
82
Matthew Barth11fc0a72020-05-26 10:55:54 -050083const option ArgumentParser::options[] = {
84 {"path", required_argument, NULL, 'p'},
85 {"type", required_argument, NULL, 't'},
86 {"code", required_argument, NULL, 'c'},
87 {0, 0, 0, 0},
Brad Bishopf138c562017-06-15 23:08:09 -040088};
89
90const char* ArgumentParser::optionstr = "p:t:c:";
91
92const std::string ArgumentParser::true_string = "true";
93const std::string ArgumentParser::empty_string = "";
94
95static void exit_with_error(const char* err, char** argv)
96{
97 ArgumentParser::usage(argv);
98 std::cerr << "\n";
99 std::cerr << "ERROR: " << err << "\n";
William A. Kennington III3e781062018-10-19 17:18:34 -0700100 exit(1);
Brad Bishopf138c562017-06-15 23:08:09 -0400101}
102
103} // namespace util
104} // namespace fan
105} // namespace phosphor
106
107int main(int argc, char* argv[])
108{
109 using namespace phosphor::fan::util;
110
111 auto options = std::make_unique<ArgumentParser>(argc, argv);
112 auto path = (*options)["path"];
113 auto stype = (*options)["type"];
114 auto scode = (*options)["code"];
115 unsigned int type = EV_KEY;
116
117 if (path == ArgumentParser::empty_string)
118 {
119 exit_with_error("Path not specified or invalid.", argv);
120 }
121 if (stype != ArgumentParser::empty_string)
122 {
123 type = stoul(stype);
124 }
125
126 if (scode == ArgumentParser::empty_string)
127 {
128 exit_with_error("Keycode not specified or invalid.", argv);
129 }
130 options.reset();
131
132 auto loop = sdevent::event::newDefault();
133 phosphor::fan::util::FileDescriptor fd(
Matthew Barth11fc0a72020-05-26 10:55:54 -0500134 open(path.c_str(), O_RDONLY | O_NONBLOCK));
Brad Bishopf138c562017-06-15 23:08:09 -0400135 auto evdev = evdevpp::evdev::newFromFD(fd());
Matthew Barth11fc0a72020-05-26 10:55:54 -0500136 sdevent::event::io::IO callback(loop, fd(), [&evdev](auto& s) {
137 unsigned int type, code, value;
138 std::tie(type, code, value) = evdev.next();
139 std::cout << "type: " << libevdev_event_type_get_name(type)
140 << " code: " << libevdev_event_code_get_name(type, code)
141 << " value: " << value << "\n";
142 });
Brad Bishopf138c562017-06-15 23:08:09 -0400143
144 auto value = evdev.fetch(type, stoul(scode));
Matthew Barth11fc0a72020-05-26 10:55:54 -0500145 std::cout << "type: " << libevdev_event_type_get_name(type)
146 << " code: " << libevdev_event_code_get_name(type, stoul(scode))
147 << " value: " << value << "\n";
Brad Bishopf138c562017-06-15 23:08:09 -0400148
149 loop.loop();
150
151 return 0;
152}