blob: 26163a7e960baf1405d1fcc931869528a37a3742 [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
17#include <algorithm>
18#include <cassert>
19#include <iostream>
20#include <iterator>
21#include <memory>
22#include "argument.hpp"
23#include "evdevpp/evdev.hpp"
24#include "sdevent/event.hpp"
25#include "sdevent/io.hpp"
26#include "utility.hpp"
27
28namespace phosphor
29{
30namespace fan
31{
32namespace util
33{
34
35ArgumentParser::ArgumentParser(int argc, char** argv)
36{
37 auto option = 0;
38 while (-1 != (option = getopt_long(argc, argv, optionstr, options, NULL)))
39 {
40 if ((option == '?') || (option == 'h'))
41 {
42 usage(argv);
43 exit(-1);
44 }
45
46 auto i = &options[0];
47 while ((i->val != option) && (i->val != 0))
48 {
49 ++i;
50 }
51
52 if (i->val)
53 {
54 arguments[i->name] = (i->has_arg ? optarg : true_string);
55 }
56 }
57}
58
59const std::string& ArgumentParser::operator[](const std::string& opt)
60{
61 auto i = arguments.find(opt);
62 if (i == arguments.end())
63 {
64 return empty_string;
65 }
66 else
67 {
68 return i->second;
69 }
70}
71
72void ArgumentParser::usage(char** argv)
73{
74 std::cerr << "Usage: " << argv[0] << " [options]\n";
75 std::cerr << "Options:\n";
76 std::cerr << " --path evdev devpath\n";
77 std::cerr << " --type evdev type\n";
78 std::cerr << " --code evdev code\n";
79 std::cerr << std::flush;
80}
81
82const option ArgumentParser::options[] =
83{
84 { "path", required_argument, NULL, 'p' },
85 { "type", required_argument, NULL, 't' },
86 { "code", required_argument, NULL, 'c' },
87 { 0, 0, 0, 0},
88};
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";
100 exit(-1);
101}
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(
134 open(path.c_str(), O_RDONLY | O_NONBLOCK));
135 auto evdev = evdevpp::evdev::newFromFD(fd());
136 sdevent::event::io::IO callback(
137 loop,
138 fd(),
139 [&evdev](auto& s)
140 {
141 unsigned int type, code, value;
142 std::tie(type, code, value) = evdev.next();
143 std::cout <<
144 "type: " << libevdev_event_type_get_name(type) <<
145 " code: " << libevdev_event_code_get_name(type, code) <<
146 " value: " << value << "\n";
147 });
148
149 auto value = evdev.fetch(type, stoul(scode));
150 std::cout <<
151 "type: " << libevdev_event_type_get_name(type) <<
152 " code: " << libevdev_event_code_get_name(type, stoul(scode)) <<
153 " value: " << value << "\n";
154
155 loop.loop();
156
157 return 0;
158}