1 /*
2  * Copyright (C) 2014 Satoshi Noguchi
3  * Copyright (C) 2014 Synaptics Inc
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <stdio.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <getopt.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <dirent.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <string>
29 #include <sstream>
30 #include <stdlib.h>
31 #include <signal.h>
32 
33 #include "hiddevice.h"
34 #include "f54test.h"
35 #include "display.h"
36 
37 #define F54TEST_GETOPTS	"hd:r:cn"
38 
39 static bool stopRequested;
40 
printHelp(const char * prog_name)41 void printHelp(const char *prog_name)
42 {
43 	fprintf(stdout, "Usage: %s [OPTIONS]\n", prog_name);
44 	fprintf(stdout, "\t-h, --help\tPrint this message\n");
45 	fprintf(stdout, "\t-d, --device\thidraw device file associated with the device being tested.\n");
46 	fprintf(stdout, "\t-r, --report_type\tReport type.\n");
47 	fprintf(stdout, "\t-c, --continuous\tContinuous mode.\n");
48 	fprintf(stdout, "\t-n, --no_reset\tDo not reset after the report.\n");
49 }
50 
RunF54Test(const char * deviceFile,f54_report_types reportType,bool continuousMode,bool noReset)51 int RunF54Test(const char * deviceFile, f54_report_types reportType, bool continuousMode, bool noReset)
52 {
53 	int rc;
54 	HIDDevice rmidevice;
55 	Display * display;
56 
57 	if (continuousMode)
58 	{
59 		display = new AnsiConsole();
60 	}
61 	else
62 	{
63 		display = new Display();
64 	}
65 
66 	display->Clear();
67 
68 	rc = rmidevice.Open(deviceFile);
69 	if (rc)
70 		return rc;
71 
72 	F54Test f54Test(rmidevice, *display);
73 
74 	rc = f54Test.Prepare(reportType);
75 	if (rc)
76 		return rc;
77 
78 	stopRequested = false;
79 
80 	do {
81 		rc = f54Test.Run();
82 	}
83 	while (continuousMode && !stopRequested);
84 
85 	if (!noReset)
86 		rmidevice.Reset();
87 
88 	rmidevice.Close();
89 
90 	delete display;
91 
92 	return rc;
93 }
94 
SignalHandler(int p_signame)95 void SignalHandler(int p_signame)
96 {
97 	stopRequested = true;
98 }
99 
main(int argc,char ** argv)100 int main(int argc, char **argv)
101 {
102 	int rc = 0;
103 	int opt;
104 	int index;
105 	char *deviceName = NULL;
106 	static struct option long_options[] = {
107 		{"help", 0, NULL, 'h'},
108 		{"device", 1, NULL, 'd'},
109 		{"report_type", 1, NULL, 'r'},
110 		{"continuous", 0, NULL, 'c'},
111 		{"no_reset", 0, NULL, 'n'},
112 		{0, 0, 0, 0},
113 	};
114 	struct dirent * devDirEntry;
115 	DIR * devDir;
116 	f54_report_types reportType = F54_16BIT_IMAGE;
117 	bool continuousMode = false;
118 	bool noReset = false;
119 
120 	while ((opt = getopt_long(argc, argv, F54TEST_GETOPTS, long_options, &index)) != -1) {
121 		switch (opt) {
122 			case 'h':
123 				printHelp(argv[0]);
124 				return 0;
125 			case 'd':
126 				deviceName = optarg;
127 				break;
128 			case 'r':
129 				reportType = (f54_report_types)strtol(optarg, NULL, 0);
130 				break;
131 			case 'c':
132 				continuousMode = true;
133 				break;
134 			case 'n':
135 				noReset = true;
136 				break;
137 			default:
138 				break;
139 
140 		}
141 	}
142 
143 	if (continuousMode)
144 	{
145 		signal(SIGHUP, SignalHandler);
146 		signal(SIGINT, SignalHandler);
147 		signal(SIGTERM, SignalHandler);
148 	}
149 
150 	if (deviceName) {
151 		rc = RunF54Test(deviceName, reportType, continuousMode, noReset);
152 		if (rc)
153 			return rc;
154 
155 		return rc;
156 	} else {
157 		char rawDevice[PATH_MAX];
158 		char deviceFile[PATH_MAX];
159 		bool found = false;
160 
161 		devDir = opendir("/dev");
162 		if (!devDir)
163 			return -1;
164 
165 		while ((devDirEntry = readdir(devDir)) != NULL) {
166 			if (strstr(devDirEntry->d_name, "hidraw")) {
167 				strncpy(rawDevice, devDirEntry->d_name, PATH_MAX);
168 				snprintf(deviceFile, PATH_MAX, "/dev/%s", devDirEntry->d_name);
169 				rc = RunF54Test(deviceFile, reportType, continuousMode, noReset);
170 				if (rc != 0) {
171 					continue;
172 				} else {
173 					found = true;
174 					break;
175 				}
176 			}
177 		}
178 		closedir(devDir);
179 
180 		if (!found)
181 			return rc;
182 	}
183 
184 	return 0;
185 }
186