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
39static bool stopRequested;
40
41void 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
51int 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
95void SignalHandler(int p_signame)
96{
97	stopRequested = true;
98}
99
100int 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