xref: /aosp_15_r20/external/rmi4utils/rmi4update/main.cpp (revision a248dafd7653b99fc45f9d29e5f139b04f2f28bc)
1*a248dafdSChristopher Ferris /*
2*a248dafdSChristopher Ferris  * Copyright (C) 2014 Andrew Duggan
3*a248dafdSChristopher Ferris  * Copyright (C) 2014 Synaptics Inc
4*a248dafdSChristopher Ferris  *
5*a248dafdSChristopher Ferris  * Licensed under the Apache License, Version 2.0 (the "License");
6*a248dafdSChristopher Ferris  * you may not use this file except in compliance with the License.
7*a248dafdSChristopher Ferris  * You may obtain a copy of the License at
8*a248dafdSChristopher Ferris  *
9*a248dafdSChristopher Ferris  *      http://www.apache.org/licenses/LICENSE-2.0
10*a248dafdSChristopher Ferris  *
11*a248dafdSChristopher Ferris  * Unless required by applicable law or agreed to in writing, software
12*a248dafdSChristopher Ferris  * distributed under the License is distributed on an "AS IS" BASIS,
13*a248dafdSChristopher Ferris  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*a248dafdSChristopher Ferris  * See the License for the specific language governing permissions and
15*a248dafdSChristopher Ferris  * limitations under the License.
16*a248dafdSChristopher Ferris  */
17*a248dafdSChristopher Ferris 
18*a248dafdSChristopher Ferris #include <stdio.h>
19*a248dafdSChristopher Ferris #include <string.h>
20*a248dafdSChristopher Ferris #include <errno.h>
21*a248dafdSChristopher Ferris #include <getopt.h>
22*a248dafdSChristopher Ferris #include <sys/types.h>
23*a248dafdSChristopher Ferris #include <sys/stat.h>
24*a248dafdSChristopher Ferris #include <fcntl.h>
25*a248dafdSChristopher Ferris #include <dirent.h>
26*a248dafdSChristopher Ferris #include <unistd.h>
27*a248dafdSChristopher Ferris #include <time.h>
28*a248dafdSChristopher Ferris #include <string>
29*a248dafdSChristopher Ferris #include <sstream>
30*a248dafdSChristopher Ferris #include <time.h>
31*a248dafdSChristopher Ferris 
32*a248dafdSChristopher Ferris #include "hiddevice.h"
33*a248dafdSChristopher Ferris #include "rmi4update.h"
34*a248dafdSChristopher Ferris 
35*a248dafdSChristopher Ferris #define VERSION_MAJOR		1
36*a248dafdSChristopher Ferris #define VERSION_MINOR		3
37*a248dafdSChristopher Ferris #define VERSION_SUBMINOR	12
38*a248dafdSChristopher Ferris 
39*a248dafdSChristopher Ferris #define RMI4UPDATE_GETOPTS	"hfd:t:pclvm"
40*a248dafdSChristopher Ferris 
41*a248dafdSChristopher Ferris bool needDebugMessage;
42*a248dafdSChristopher Ferris 
printHelp(const char * prog_name)43*a248dafdSChristopher Ferris void printHelp(const char *prog_name)
44*a248dafdSChristopher Ferris {
45*a248dafdSChristopher Ferris 	fprintf(stdout, "Usage: %s [OPTIONS] FIRMWAREFILE\n", prog_name);
46*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-h, --help\t\tPrint this message\n");
47*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-f, --force\t\tForce updating firmware even it the image provided is older\n\t\t\t\tthen the current firmware on the device.\n");
48*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-d, --device\t\thidraw device file associated with the device being updated.\n");
49*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-p, --fw-props\t\tPrint the firmware properties.\n");
50*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-c, --config-id\t\tPrint the config id.\n");
51*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-l, --lockdown\t\tPerform lockdown.\n");
52*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-v, --version\t\tPrint version number.\n");
53*a248dafdSChristopher Ferris 	fprintf(stdout, "\t-t, --device-type\tFilter by device type [touchpad or touchscreen].\n");
54*a248dafdSChristopher Ferris }
55*a248dafdSChristopher Ferris 
printVersion()56*a248dafdSChristopher Ferris void printVersion()
57*a248dafdSChristopher Ferris {
58*a248dafdSChristopher Ferris 	fprintf(stdout, "rmi4update version %d.%d.%d\n",
59*a248dafdSChristopher Ferris 		VERSION_MAJOR, VERSION_MINOR, VERSION_SUBMINOR);
60*a248dafdSChristopher Ferris }
61*a248dafdSChristopher Ferris 
GetFirmwareProps(const char * deviceFile,std::string & props,bool configid)62*a248dafdSChristopher Ferris int GetFirmwareProps(const char * deviceFile, std::string &props, bool configid)
63*a248dafdSChristopher Ferris {
64*a248dafdSChristopher Ferris 	HIDDevice rmidevice;
65*a248dafdSChristopher Ferris 	int rc = UPDATE_SUCCESS;
66*a248dafdSChristopher Ferris 	std::stringstream ss;
67*a248dafdSChristopher Ferris 
68*a248dafdSChristopher Ferris 	rc = rmidevice.Open(deviceFile);
69*a248dafdSChristopher Ferris 	if (rc)
70*a248dafdSChristopher Ferris 		return rc;
71*a248dafdSChristopher Ferris 
72*a248dafdSChristopher Ferris 	if (needDebugMessage)
73*a248dafdSChristopher Ferris 		rmidevice.m_hasDebug = true;
74*a248dafdSChristopher Ferris 
75*a248dafdSChristopher Ferris 	// Clear all interrupts before parsing to avoid unexpected interrupts.
76*a248dafdSChristopher Ferris 	rmidevice.ToggleInterruptMask(false);
77*a248dafdSChristopher Ferris 
78*a248dafdSChristopher Ferris 	rmidevice.ScanPDT(0x1);
79*a248dafdSChristopher Ferris 	rmidevice.QueryBasicProperties();
80*a248dafdSChristopher Ferris 
81*a248dafdSChristopher Ferris 	// Restore the interrupts
82*a248dafdSChristopher Ferris 	rmidevice.ToggleInterruptMask(true);
83*a248dafdSChristopher Ferris 
84*a248dafdSChristopher Ferris 	if (configid) {
85*a248dafdSChristopher Ferris 		ss << std::hex << rmidevice.GetConfigID();
86*a248dafdSChristopher Ferris 	} else {
87*a248dafdSChristopher Ferris 		ss << rmidevice.GetFirmwareVersionMajor() << "."
88*a248dafdSChristopher Ferris 			<< rmidevice.GetFirmwareVersionMinor() << "."
89*a248dafdSChristopher Ferris 			<< rmidevice.GetFirmwareID();
90*a248dafdSChristopher Ferris 
91*a248dafdSChristopher Ferris 		if (rmidevice.InBootloader())
92*a248dafdSChristopher Ferris 			ss << " bootloader";
93*a248dafdSChristopher Ferris 	}
94*a248dafdSChristopher Ferris 
95*a248dafdSChristopher Ferris 	props = ss.str();
96*a248dafdSChristopher Ferris 
97*a248dafdSChristopher Ferris 	return rc;
98*a248dafdSChristopher Ferris }
99*a248dafdSChristopher Ferris 
main(int argc,char ** argv)100*a248dafdSChristopher Ferris int main(int argc, char **argv)
101*a248dafdSChristopher Ferris {
102*a248dafdSChristopher Ferris 	int rc;
103*a248dafdSChristopher Ferris 	FirmwareImage image;
104*a248dafdSChristopher Ferris 	int opt;
105*a248dafdSChristopher Ferris 	int index;
106*a248dafdSChristopher Ferris 	char *deviceName = NULL;
107*a248dafdSChristopher Ferris 	const char *firmwareName = NULL;
108*a248dafdSChristopher Ferris 	bool force = false;
109*a248dafdSChristopher Ferris 	static struct option long_options[] = {
110*a248dafdSChristopher Ferris 		{"help", 0, NULL, 'h'},
111*a248dafdSChristopher Ferris 		{"force", 0, NULL, 'f'},
112*a248dafdSChristopher Ferris 		{"device", 1, NULL, 'd'},
113*a248dafdSChristopher Ferris 		{"fw-props", 0, NULL, 'p'},
114*a248dafdSChristopher Ferris 		{"config-id", 0, NULL, 'c'},
115*a248dafdSChristopher Ferris 		{"lockdown", 0, NULL, 'l'},
116*a248dafdSChristopher Ferris 		{"version", 0, NULL, 'v'},
117*a248dafdSChristopher Ferris 		{"device-type", 1, NULL, 't'},
118*a248dafdSChristopher Ferris 		{0, 0, 0, 0},
119*a248dafdSChristopher Ferris 	};
120*a248dafdSChristopher Ferris 	bool printFirmwareProps = false;
121*a248dafdSChristopher Ferris 	bool printConfigid = false;
122*a248dafdSChristopher Ferris 	bool performLockdown = false;
123*a248dafdSChristopher Ferris 	needDebugMessage = false;
124*a248dafdSChristopher Ferris 	HIDDevice device;
125*a248dafdSChristopher Ferris 	enum RMIDeviceType deviceType = RMI_DEVICE_TYPE_ANY;
126*a248dafdSChristopher Ferris 
127*a248dafdSChristopher Ferris 	while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) {
128*a248dafdSChristopher Ferris 		switch (opt) {
129*a248dafdSChristopher Ferris 			case 'h':
130*a248dafdSChristopher Ferris 				printHelp(argv[0]);
131*a248dafdSChristopher Ferris 				return 0;
132*a248dafdSChristopher Ferris 			case 'f':
133*a248dafdSChristopher Ferris 				force = true;
134*a248dafdSChristopher Ferris 				break;
135*a248dafdSChristopher Ferris 			case 'd':
136*a248dafdSChristopher Ferris 				deviceName = optarg;
137*a248dafdSChristopher Ferris 				break;
138*a248dafdSChristopher Ferris 			case 'p':
139*a248dafdSChristopher Ferris 				printFirmwareProps = true;
140*a248dafdSChristopher Ferris 				break;
141*a248dafdSChristopher Ferris 			case 'c':
142*a248dafdSChristopher Ferris 				printFirmwareProps = true;
143*a248dafdSChristopher Ferris 				printConfigid = true;
144*a248dafdSChristopher Ferris 				break;
145*a248dafdSChristopher Ferris 			case 'l':
146*a248dafdSChristopher Ferris 				performLockdown = true;
147*a248dafdSChristopher Ferris 				break;
148*a248dafdSChristopher Ferris 			case 't':
149*a248dafdSChristopher Ferris 				if (!strcasecmp((const char *)optarg, "touchpad"))
150*a248dafdSChristopher Ferris 					deviceType = RMI_DEVICE_TYPE_TOUCHPAD;
151*a248dafdSChristopher Ferris 				else if (!strcasecmp((const char *)optarg, "touchscreen"))
152*a248dafdSChristopher Ferris 					deviceType = RMI_DEVICE_TYPE_TOUCHSCREEN;
153*a248dafdSChristopher Ferris 				break;
154*a248dafdSChristopher Ferris 			case 'v':
155*a248dafdSChristopher Ferris 				printVersion();
156*a248dafdSChristopher Ferris 				return 0;
157*a248dafdSChristopher Ferris 			case 'm':
158*a248dafdSChristopher Ferris 				needDebugMessage = true;
159*a248dafdSChristopher Ferris 				break;
160*a248dafdSChristopher Ferris 			default:
161*a248dafdSChristopher Ferris 				break;
162*a248dafdSChristopher Ferris 
163*a248dafdSChristopher Ferris 		}
164*a248dafdSChristopher Ferris 	}
165*a248dafdSChristopher Ferris 
166*a248dafdSChristopher Ferris 	if (printFirmwareProps) {
167*a248dafdSChristopher Ferris 		std::string props;
168*a248dafdSChristopher Ferris 
169*a248dafdSChristopher Ferris 		if (!deviceName) {
170*a248dafdSChristopher Ferris 			fprintf(stderr, "Specifiy which device to query\n");
171*a248dafdSChristopher Ferris 			return 1;
172*a248dafdSChristopher Ferris 		}
173*a248dafdSChristopher Ferris 		rc = GetFirmwareProps(deviceName, props, printConfigid);
174*a248dafdSChristopher Ferris 		if (rc) {
175*a248dafdSChristopher Ferris 			fprintf(stderr, "Failed to read properties from device: %s\n", update_err_to_string(rc));
176*a248dafdSChristopher Ferris 			return 1;
177*a248dafdSChristopher Ferris 		}
178*a248dafdSChristopher Ferris 		fprintf(stdout, "%s\n", props.c_str());
179*a248dafdSChristopher Ferris 		return 0;
180*a248dafdSChristopher Ferris 	}
181*a248dafdSChristopher Ferris 
182*a248dafdSChristopher Ferris 	if (optind < argc) {
183*a248dafdSChristopher Ferris 		firmwareName = argv[optind];
184*a248dafdSChristopher Ferris 	} else {
185*a248dafdSChristopher Ferris 		printHelp(argv[0]);
186*a248dafdSChristopher Ferris 		return -1;
187*a248dafdSChristopher Ferris 	}
188*a248dafdSChristopher Ferris 
189*a248dafdSChristopher Ferris 	rc = image.Initialize(firmwareName);
190*a248dafdSChristopher Ferris 	if (rc != UPDATE_SUCCESS) {
191*a248dafdSChristopher Ferris 		fprintf(stderr, "Failed to initialize the firmware image: %s\n", update_err_to_string(rc));
192*a248dafdSChristopher Ferris 		return 1;
193*a248dafdSChristopher Ferris 	}
194*a248dafdSChristopher Ferris 
195*a248dafdSChristopher Ferris 	if (deviceName) {
196*a248dafdSChristopher Ferris 		 rc = device.Open(deviceName);
197*a248dafdSChristopher Ferris 		 if (rc) {
198*a248dafdSChristopher Ferris 			fprintf(stderr, "%s: failed to initialize rmi device (%d): %s\n", argv[0], errno,
199*a248dafdSChristopher Ferris 				strerror(errno));
200*a248dafdSChristopher Ferris 			return 1;
201*a248dafdSChristopher Ferris 		}
202*a248dafdSChristopher Ferris 	} else {
203*a248dafdSChristopher Ferris 		if (!device.FindDevice(deviceType))
204*a248dafdSChristopher Ferris 			return 1;
205*a248dafdSChristopher Ferris 	}
206*a248dafdSChristopher Ferris 
207*a248dafdSChristopher Ferris 	if (needDebugMessage) {
208*a248dafdSChristopher Ferris 		device.m_hasDebug = true;
209*a248dafdSChristopher Ferris 	}
210*a248dafdSChristopher Ferris 
211*a248dafdSChristopher Ferris 	RMI4Update update(device, image);
212*a248dafdSChristopher Ferris 	rc = update.UpdateFirmware(force, performLockdown);
213*a248dafdSChristopher Ferris 
214*a248dafdSChristopher Ferris 	if (rc != UPDATE_SUCCESS)
215*a248dafdSChristopher Ferris 	{
216*a248dafdSChristopher Ferris 		device.Reset();
217*a248dafdSChristopher Ferris 		return 1;
218*a248dafdSChristopher Ferris 	}
219*a248dafdSChristopher Ferris 
220*a248dafdSChristopher Ferris 	return 0;
221*a248dafdSChristopher Ferris }
222