• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 Andrew Duggan
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 <time.h>
31 
32 #include "hiddevice.h"
33 #include "rmi4update.h"
34 
35 #define VERSION_MAJOR		1
36 #define VERSION_MINOR		3
37 #define VERSION_SUBMINOR	12
38 
39 #define RMI4UPDATE_GETOPTS	"hfd:t:pclvm"
40 
41 bool needDebugMessage;
42 
printHelp(const char * prog_name)43 void printHelp(const char *prog_name)
44 {
45 	fprintf(stdout, "Usage: %s [OPTIONS] FIRMWAREFILE\n", prog_name);
46 	fprintf(stdout, "\t-h, --help\t\tPrint this message\n");
47 	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 	fprintf(stdout, "\t-d, --device\t\thidraw device file associated with the device being updated.\n");
49 	fprintf(stdout, "\t-p, --fw-props\t\tPrint the firmware properties.\n");
50 	fprintf(stdout, "\t-c, --config-id\t\tPrint the config id.\n");
51 	fprintf(stdout, "\t-l, --lockdown\t\tPerform lockdown.\n");
52 	fprintf(stdout, "\t-v, --version\t\tPrint version number.\n");
53 	fprintf(stdout, "\t-t, --device-type\tFilter by device type [touchpad or touchscreen].\n");
54 }
55 
printVersion()56 void printVersion()
57 {
58 	fprintf(stdout, "rmi4update version %d.%d.%d\n",
59 		VERSION_MAJOR, VERSION_MINOR, VERSION_SUBMINOR);
60 }
61 
GetFirmwareProps(const char * deviceFile,std::string & props,bool configid)62 int GetFirmwareProps(const char * deviceFile, std::string &props, bool configid)
63 {
64 	HIDDevice rmidevice;
65 	int rc = UPDATE_SUCCESS;
66 	std::stringstream ss;
67 
68 	rc = rmidevice.Open(deviceFile);
69 	if (rc)
70 		return rc;
71 
72 	if (needDebugMessage)
73 		rmidevice.m_hasDebug = true;
74 
75 	// Clear all interrupts before parsing to avoid unexpected interrupts.
76 	rmidevice.ToggleInterruptMask(false);
77 
78 	rmidevice.ScanPDT(0x1);
79 	rmidevice.QueryBasicProperties();
80 
81 	// Restore the interrupts
82 	rmidevice.ToggleInterruptMask(true);
83 
84 	if (configid) {
85 		ss << std::hex << rmidevice.GetConfigID();
86 	} else {
87 		ss << rmidevice.GetFirmwareVersionMajor() << "."
88 			<< rmidevice.GetFirmwareVersionMinor() << "."
89 			<< rmidevice.GetFirmwareID();
90 
91 		if (rmidevice.InBootloader())
92 			ss << " bootloader";
93 	}
94 
95 	props = ss.str();
96 
97 	return rc;
98 }
99 
main(int argc,char ** argv)100 int main(int argc, char **argv)
101 {
102 	int rc;
103 	FirmwareImage image;
104 	int opt;
105 	int index;
106 	char *deviceName = NULL;
107 	const char *firmwareName = NULL;
108 	bool force = false;
109 	static struct option long_options[] = {
110 		{"help", 0, NULL, 'h'},
111 		{"force", 0, NULL, 'f'},
112 		{"device", 1, NULL, 'd'},
113 		{"fw-props", 0, NULL, 'p'},
114 		{"config-id", 0, NULL, 'c'},
115 		{"lockdown", 0, NULL, 'l'},
116 		{"version", 0, NULL, 'v'},
117 		{"device-type", 1, NULL, 't'},
118 		{0, 0, 0, 0},
119 	};
120 	bool printFirmwareProps = false;
121 	bool printConfigid = false;
122 	bool performLockdown = false;
123 	needDebugMessage = false;
124 	HIDDevice device;
125 	enum RMIDeviceType deviceType = RMI_DEVICE_TYPE_ANY;
126 
127 	while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) {
128 		switch (opt) {
129 			case 'h':
130 				printHelp(argv[0]);
131 				return 0;
132 			case 'f':
133 				force = true;
134 				break;
135 			case 'd':
136 				deviceName = optarg;
137 				break;
138 			case 'p':
139 				printFirmwareProps = true;
140 				break;
141 			case 'c':
142 				printFirmwareProps = true;
143 				printConfigid = true;
144 				break;
145 			case 'l':
146 				performLockdown = true;
147 				break;
148 			case 't':
149 				if (!strcasecmp((const char *)optarg, "touchpad"))
150 					deviceType = RMI_DEVICE_TYPE_TOUCHPAD;
151 				else if (!strcasecmp((const char *)optarg, "touchscreen"))
152 					deviceType = RMI_DEVICE_TYPE_TOUCHSCREEN;
153 				break;
154 			case 'v':
155 				printVersion();
156 				return 0;
157 			case 'm':
158 				needDebugMessage = true;
159 				break;
160 			default:
161 				break;
162 
163 		}
164 	}
165 
166 	if (printFirmwareProps) {
167 		std::string props;
168 
169 		if (!deviceName) {
170 			fprintf(stderr, "Specifiy which device to query\n");
171 			return 1;
172 		}
173 		rc = GetFirmwareProps(deviceName, props, printConfigid);
174 		if (rc) {
175 			fprintf(stderr, "Failed to read properties from device: %s\n", update_err_to_string(rc));
176 			return 1;
177 		}
178 		fprintf(stdout, "%s\n", props.c_str());
179 		return 0;
180 	}
181 
182 	if (optind < argc) {
183 		firmwareName = argv[optind];
184 	} else {
185 		printHelp(argv[0]);
186 		return -1;
187 	}
188 
189 	rc = image.Initialize(firmwareName);
190 	if (rc != UPDATE_SUCCESS) {
191 		fprintf(stderr, "Failed to initialize the firmware image: %s\n", update_err_to_string(rc));
192 		return 1;
193 	}
194 
195 	if (deviceName) {
196 		 rc = device.Open(deviceName);
197 		 if (rc) {
198 			fprintf(stderr, "%s: failed to initialize rmi device (%d): %s\n", argv[0], errno,
199 				strerror(errno));
200 			return 1;
201 		}
202 	} else {
203 		if (!device.FindDevice(deviceType))
204 			return 1;
205 	}
206 
207 	if (needDebugMessage) {
208 		device.m_hasDebug = true;
209 	}
210 
211 	RMI4Update update(device, image);
212 	rc = update.UpdateFirmware(force, performLockdown);
213 
214 	if (rc != UPDATE_SUCCESS)
215 	{
216 		device.Reset();
217 		return 1;
218 	}
219 
220 	return 0;
221 }
222