• Home
  • History
  • Annotate
  • 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  
31  #include "hiddevice.h"
32  #include "rmi4update.h"
33  
34  #define VERSION_MAJOR		1
35  #define VERSION_MINOR		2
36  #define VERSION_SUBMINOR	0
37  
38  #define RMI4UPDATE_GETOPTS	"hfd:plv"
39  
printHelp(const char * prog_name)40  void printHelp(const char *prog_name)
41  {
42  	fprintf(stdout, "Usage: %s [OPTIONS] FIRMWAREFILE\n", prog_name);
43  	fprintf(stdout, "\t-h, --help\tPrint this message\n");
44  	fprintf(stdout, "\t-f, --force\tForce updating firmware even it the image provided is older\n\t\t\tthen the current firmware on the device.\n");
45  	fprintf(stdout, "\t-d, --device\thidraw device file associated with the device being updated.\n");
46  	fprintf(stdout, "\t-p, --fw-props\tPrint the firmware properties.\n");
47  	fprintf(stdout, "\t-l, --lockdown\tPerform lockdown.\n");
48  	fprintf(stdout, "\t-v, --version\tPrint version number.\n");
49  }
50  
printVersion()51  void printVersion()
52  {
53  	fprintf(stdout, "rmi4update version %d.%d.%d\n",
54  		VERSION_MAJOR, VERSION_MINOR, VERSION_SUBMINOR);
55  }
56  
UpdateDevice(FirmwareImage & image,bool force,bool performLockdown,const char * deviceFile)57  int UpdateDevice(FirmwareImage & image, bool force, bool performLockdown, const char * deviceFile)
58  {
59  	HIDDevice rmidevice;
60  	int rc;
61  
62  	rc = rmidevice.Open(deviceFile);
63  	if (rc)
64  		return rc;
65  
66  	RMI4Update update(rmidevice, image);
67  	rc = update.UpdateFirmware(force, performLockdown);
68  	if (rc != UPDATE_SUCCESS)
69  		return rc;
70  
71  	return rc;
72  }
73  
GetFirmwareProps(const char * deviceFile,std::string & props)74  int GetFirmwareProps(const char * deviceFile, std::string &props)
75  {
76  	HIDDevice rmidevice;
77  	int rc = UPDATE_SUCCESS;
78  	std::stringstream ss;
79  
80  	rc = rmidevice.Open(deviceFile);
81  	if (rc)
82  		return rc;
83  
84  	rmidevice.ScanPDT(0x1);
85  	rmidevice.QueryBasicProperties();
86  
87  	ss << rmidevice.GetFirmwareVersionMajor() << "."
88  		<< rmidevice.GetFirmwareVersionMinor() << "."
89  		<< std::hex << rmidevice.GetFirmwareID();
90  
91  	if (rmidevice.InBootloader())
92  		ss << " bootloader";
93  
94  	props = ss.str();
95  
96  	return rc;
97  }
98  
main(int argc,char ** argv)99  int main(int argc, char **argv)
100  {
101  	int rc;
102  	FirmwareImage image;
103  	int opt;
104  	int index;
105  	char *deviceName = NULL;
106  	const char *firmwareName = NULL;
107  	bool force = false;
108  	static struct option long_options[] = {
109  		{"help", 0, NULL, 'h'},
110  		{"force", 0, NULL, 'f'},
111  		{"device", 1, NULL, 'd'},
112  		{"fw-props", 0, NULL, 'p'},
113  		{"lockdown", 0, NULL, 'l'},
114  		{"version", 0, NULL, 'v'},
115  		{0, 0, 0, 0},
116  	};
117  	struct dirent * devDirEntry;
118  	DIR * devDir;
119  	bool printFirmwareProps = false;
120  	bool performLockdown = false;
121  
122  	while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) {
123  		switch (opt) {
124  			case 'h':
125  				printHelp(argv[0]);
126  				return 0;
127  			case 'f':
128  				force = true;
129  				break;
130  			case 'd':
131  				deviceName = optarg;
132  				break;
133  			case 'p':
134  				printFirmwareProps = true;
135  				break;
136  			case 'l':
137  				performLockdown = true;
138  				break;
139  			case 'v':
140  				printVersion();
141  				return 0;
142  			default:
143  				break;
144  
145  		}
146  	}
147  
148  	if (printFirmwareProps) {
149  		std::string props;
150  
151  		if (!deviceName) {
152  			fprintf(stderr, "Specifiy which device to query\n");
153  			return 1;
154  		}
155  		rc = GetFirmwareProps(deviceName, props);
156  		if (rc) {
157  			fprintf(stderr, "Failed to read properties from device: %s\n", update_err_to_string(rc));
158  			return 1;
159  		}
160  		fprintf(stdout, "%s\n", props.c_str());
161  		return 0;
162  	}
163  
164  	if (optind < argc) {
165  		firmwareName = argv[optind];
166  	} else {
167  		printHelp(argv[0]);
168  		return -1;
169  	}
170  
171  	rc = image.Initialize(firmwareName);
172  	if (rc != UPDATE_SUCCESS) {
173  		fprintf(stderr, "Failed to initialize the firmware image: %s\n", update_err_to_string(rc));
174  		return 1;
175  	}
176  
177  	if (deviceName) {
178  		rc = UpdateDevice(image, force, performLockdown, deviceName);
179  
180  		return rc;
181  	} else {
182  		char deviceFile[PATH_MAX];
183  		bool found = false;
184  
185  		devDir = opendir("/dev");
186  		if (!devDir)
187  			return -1;
188  
189  		while ((devDirEntry = readdir(devDir)) != NULL) {
190  			if (strstr(devDirEntry->d_name, "hidraw")) {
191  				char rawDevice[PATH_MAX];
192  				strncpy(rawDevice, devDirEntry->d_name, PATH_MAX);
193  				snprintf(deviceFile, PATH_MAX, "/dev/%s", devDirEntry->d_name);
194  				rc = UpdateDevice(image, force, performLockdown, deviceFile);
195  				if (rc != 0) {
196  					continue;
197  				} else {
198  					found = true;
199  					break;
200  				}
201  			}
202  		}
203  		closedir(devDir);
204  
205  		if (!found)
206  			return rc;
207  	}
208  
209  	return 0;
210  }
211