1*a248dafdSChristopher Ferris /*
2*a248dafdSChristopher Ferris * Copyright (C) 2013 - 2014 Andrew Duggan
3*a248dafdSChristopher Ferris * Copyright (C) 2013 - 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 <sys/types.h>
20*a248dafdSChristopher Ferris #include <sys/stat.h>
21*a248dafdSChristopher Ferris #include <fcntl.h>
22*a248dafdSChristopher Ferris #include <dirent.h>
23*a248dafdSChristopher Ferris #include <errno.h>
24*a248dafdSChristopher Ferris #include <string.h>
25*a248dafdSChristopher Ferris #include <unistd.h>
26*a248dafdSChristopher Ferris #include <sys/ioctl.h>
27*a248dafdSChristopher Ferris #include <sys/select.h>
28*a248dafdSChristopher Ferris #include <getopt.h>
29*a248dafdSChristopher Ferris
30*a248dafdSChristopher Ferris #include <linux/types.h>
31*a248dafdSChristopher Ferris #include <linux/input.h>
32*a248dafdSChristopher Ferris #include <linux/hidraw.h>
33*a248dafdSChristopher Ferris #include <signal.h>
34*a248dafdSChristopher Ferris #include <stdlib.h>
35*a248dafdSChristopher Ferris
36*a248dafdSChristopher Ferris #include "hiddevice.h"
37*a248dafdSChristopher Ferris
38*a248dafdSChristopher Ferris #define RMI4UPDATE_GETOPTS "hp:ir:w:foambd:ecnt:"
39*a248dafdSChristopher Ferris
40*a248dafdSChristopher Ferris enum rmihidtool_cmd {
41*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_INTERACTIVE,
42*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_READ,
43*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_WRITE,
44*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_FW_ID,
45*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_CF_ID,
46*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_PROPS,
47*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_ATTN,
48*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_PRINT_FUNCTIONS,
49*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_REBIND_DRIVER,
50*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_PRINT_DEVICE_INFO,
51*a248dafdSChristopher Ferris RMIHIDTOOL_CMD_RESET_DEVICE,
52*a248dafdSChristopher Ferris };
53*a248dafdSChristopher Ferris
54*a248dafdSChristopher Ferris static int report_attn = 0;
55*a248dafdSChristopher Ferris static RMIDevice * g_device = NULL;
56*a248dafdSChristopher Ferris
print_help(const char * prog_name)57*a248dafdSChristopher Ferris void print_help(const char *prog_name)
58*a248dafdSChristopher Ferris {
59*a248dafdSChristopher Ferris fprintf(stdout, "Usage: %s [OPTIONS] DEVICEFILE\n", prog_name);
60*a248dafdSChristopher Ferris fprintf(stdout, "\t-h, --help\t\t\t\tPrint this message\n");
61*a248dafdSChristopher Ferris fprintf(stdout, "\t-d, --device\t\t\t\thidraw device file associated with the device.\n");
62*a248dafdSChristopher Ferris fprintf(stdout, "\t-p, --protocol [protocol]\t\tSet which transport prototocl to use.\n");
63*a248dafdSChristopher Ferris fprintf(stdout, "\t-i, --interactive\t\t\tRun in interactive mode.\n");
64*a248dafdSChristopher Ferris fprintf(stdout, "\t-r, --read [address] [length]\t\tRead registers starting at the address.\n");
65*a248dafdSChristopher Ferris fprintf(stdout, "\t-w, --write [address] [length] [data]\tWrite registers starting at the address.\n");
66*a248dafdSChristopher Ferris fprintf(stdout, "\t-f, --firmware-id\t\t\tPrint the firmware id\n");
67*a248dafdSChristopher Ferris fprintf(stdout, "\t-c, --config-id\t\t\t\tPrint the config id\n");
68*a248dafdSChristopher Ferris fprintf(stdout, "\t-o, --props\t\t\t\tPrint device properties\n");
69*a248dafdSChristopher Ferris fprintf(stdout, "\t-a, --attention\t\t\t\tPrint attention reports until control + c\n");
70*a248dafdSChristopher Ferris fprintf(stdout, "\t-m, --print-functions\t\t\tPrint RMI4 functions for the device.\n");
71*a248dafdSChristopher Ferris fprintf(stdout, "\t-b, --rebind-driver\t\t\tRebind the driver to force an update of device properties.\n");
72*a248dafdSChristopher Ferris fprintf(stdout, "\t-n, --device-info\t\t\tPrint protocol specific information about the device.\n");
73*a248dafdSChristopher Ferris fprintf(stdout, "\t-e, --reset-device\t\t\tReset the device.\n");
74*a248dafdSChristopher Ferris fprintf(stdout, "\t-t, --device-type\t\t\tFilter by device type [touchpad or touchscreen].\n");
75*a248dafdSChristopher Ferris }
76*a248dafdSChristopher Ferris
print_cmd_usage()77*a248dafdSChristopher Ferris void print_cmd_usage()
78*a248dafdSChristopher Ferris {
79*a248dafdSChristopher Ferris fprintf(stdout, "Commands:\n");
80*a248dafdSChristopher Ferris fprintf(stdout, "s [0,1,2]: Set RMIMode\n");
81*a248dafdSChristopher Ferris fprintf(stdout, "r address size: read size bytes from address\n");
82*a248dafdSChristopher Ferris fprintf(stdout, "w address { values }: write bytes to address\n");
83*a248dafdSChristopher Ferris fprintf(stdout, "a: Wait for attention\n");
84*a248dafdSChristopher Ferris fprintf(stdout, "q: quit\n");
85*a248dafdSChristopher Ferris }
86*a248dafdSChristopher Ferris
find_token(char * input,char * result,size_t result_len,char ** endpp)87*a248dafdSChristopher Ferris int find_token(char * input, char * result, size_t result_len, char ** endpp)
88*a248dafdSChristopher Ferris {
89*a248dafdSChristopher Ferris int i = 0;
90*a248dafdSChristopher Ferris char * start = input;
91*a248dafdSChristopher Ferris char * end;
92*a248dafdSChristopher Ferris
93*a248dafdSChristopher Ferris while (input[i] == ' ') {
94*a248dafdSChristopher Ferris ++start;
95*a248dafdSChristopher Ferris ++i;
96*a248dafdSChristopher Ferris }
97*a248dafdSChristopher Ferris
98*a248dafdSChristopher Ferris while (input[i] != '\0') {
99*a248dafdSChristopher Ferris if (input[++i] == ' ')
100*a248dafdSChristopher Ferris break;
101*a248dafdSChristopher Ferris }
102*a248dafdSChristopher Ferris end = &input[i];
103*a248dafdSChristopher Ferris
104*a248dafdSChristopher Ferris if (start == end)
105*a248dafdSChristopher Ferris return 0;
106*a248dafdSChristopher Ferris
107*a248dafdSChristopher Ferris *endpp = end;
108*a248dafdSChristopher Ferris if (static_cast<ssize_t>(result_len) < end - start + 1)
109*a248dafdSChristopher Ferris return 0;
110*a248dafdSChristopher Ferris strncpy(result, start, end - start);
111*a248dafdSChristopher Ferris result[end - start] = '\0';
112*a248dafdSChristopher Ferris
113*a248dafdSChristopher Ferris return 1;
114*a248dafdSChristopher Ferris }
115*a248dafdSChristopher Ferris
interactive(RMIDevice * device,unsigned char * report)116*a248dafdSChristopher Ferris void interactive(RMIDevice * device, unsigned char *report)
117*a248dafdSChristopher Ferris {
118*a248dafdSChristopher Ferris char token[256];
119*a248dafdSChristopher Ferris char * start;
120*a248dafdSChristopher Ferris char * end;
121*a248dafdSChristopher Ferris int rc;
122*a248dafdSChristopher Ferris
123*a248dafdSChristopher Ferris for (;;) {
124*a248dafdSChristopher Ferris fprintf(stdout, "\n");
125*a248dafdSChristopher Ferris device->PrintDeviceInfo();
126*a248dafdSChristopher Ferris fprintf(stdout, "\n");
127*a248dafdSChristopher Ferris print_cmd_usage();
128*a248dafdSChristopher Ferris char input[256];
129*a248dafdSChristopher Ferris
130*a248dafdSChristopher Ferris if (fgets(input, 256, stdin)) {
131*a248dafdSChristopher Ferris memset(token, 0, 256);
132*a248dafdSChristopher Ferris
133*a248dafdSChristopher Ferris if (input[0] == 's') {
134*a248dafdSChristopher Ferris start = input + 2;
135*a248dafdSChristopher Ferris find_token(start, token, sizeof(token), &end);
136*a248dafdSChristopher Ferris int mode = strtol(token, NULL, 0);
137*a248dafdSChristopher Ferris if (mode >= 0 && mode <= 2) {
138*a248dafdSChristopher Ferris if (device->SetMode(mode)) {
139*a248dafdSChristopher Ferris fprintf(stderr, "Set RMI Mode to: %d\n", mode);
140*a248dafdSChristopher Ferris } else {
141*a248dafdSChristopher Ferris fprintf(stderr, "Set RMI Mode FAILED!\n");
142*a248dafdSChristopher Ferris continue;
143*a248dafdSChristopher Ferris }
144*a248dafdSChristopher Ferris }
145*a248dafdSChristopher Ferris } else if (input[0] == 'r') {
146*a248dafdSChristopher Ferris start = input + 2;
147*a248dafdSChristopher Ferris find_token(start, token, sizeof(token), &end);
148*a248dafdSChristopher Ferris start = end + 1;
149*a248dafdSChristopher Ferris unsigned int addr = strtol(token, NULL, 0);
150*a248dafdSChristopher Ferris find_token(start, token, sizeof(token), &end);
151*a248dafdSChristopher Ferris start = end + 1;
152*a248dafdSChristopher Ferris unsigned int len = strtol(token, NULL, 0);
153*a248dafdSChristopher Ferris fprintf(stdout, "Address = 0x%02x Length = %d\n", addr, len);
154*a248dafdSChristopher Ferris
155*a248dafdSChristopher Ferris memset(report, 0, 256);
156*a248dafdSChristopher Ferris rc = device->Read(addr, report, len);
157*a248dafdSChristopher Ferris if (rc < 0)
158*a248dafdSChristopher Ferris fprintf(stderr, "Failed to read report: %d\n", rc);
159*a248dafdSChristopher Ferris print_buffer(report, len);
160*a248dafdSChristopher Ferris } else if (input[0] == 'w') {
161*a248dafdSChristopher Ferris int index = 0;
162*a248dafdSChristopher Ferris start = input + 2;
163*a248dafdSChristopher Ferris find_token(start, token, sizeof(token), &end);
164*a248dafdSChristopher Ferris start = end + 1;
165*a248dafdSChristopher Ferris unsigned int addr = strtol(token, NULL, 0);
166*a248dafdSChristopher Ferris unsigned int len = 0;
167*a248dafdSChristopher Ferris
168*a248dafdSChristopher Ferris memset(report, 0, 256);
169*a248dafdSChristopher Ferris while (find_token(start, token, sizeof(token), &end)) {
170*a248dafdSChristopher Ferris start = end;
171*a248dafdSChristopher Ferris report[index++] = strtol(token, NULL, 0);
172*a248dafdSChristopher Ferris ++len;
173*a248dafdSChristopher Ferris }
174*a248dafdSChristopher Ferris
175*a248dafdSChristopher Ferris if (device->Write(addr, report, len) < 0) {
176*a248dafdSChristopher Ferris fprintf(stderr, "Failed to Write Report\n");
177*a248dafdSChristopher Ferris continue;
178*a248dafdSChristopher Ferris }
179*a248dafdSChristopher Ferris } else if (input[0] == 'a') {
180*a248dafdSChristopher Ferris unsigned int bytes = 256;
181*a248dafdSChristopher Ferris device->GetAttentionReport(NULL,
182*a248dafdSChristopher Ferris RMI_INTERUPT_SOURCES_ALL_MASK,
183*a248dafdSChristopher Ferris report, &bytes);
184*a248dafdSChristopher Ferris print_buffer(report, bytes);
185*a248dafdSChristopher Ferris } else if (input[0] == 'q') {
186*a248dafdSChristopher Ferris return;
187*a248dafdSChristopher Ferris } else {
188*a248dafdSChristopher Ferris print_cmd_usage();
189*a248dafdSChristopher Ferris }
190*a248dafdSChristopher Ferris }
191*a248dafdSChristopher Ferris }
192*a248dafdSChristopher Ferris }
193*a248dafdSChristopher Ferris
cleanup(int status)194*a248dafdSChristopher Ferris static void cleanup(int status)
195*a248dafdSChristopher Ferris {
196*a248dafdSChristopher Ferris if (report_attn) {
197*a248dafdSChristopher Ferris report_attn = 0;
198*a248dafdSChristopher Ferris if (g_device)
199*a248dafdSChristopher Ferris g_device->Cancel();
200*a248dafdSChristopher Ferris } else {
201*a248dafdSChristopher Ferris exit(0);
202*a248dafdSChristopher Ferris }
203*a248dafdSChristopher Ferris }
204*a248dafdSChristopher Ferris
main(int argc,char ** argv)205*a248dafdSChristopher Ferris int main(int argc, char ** argv)
206*a248dafdSChristopher Ferris {
207*a248dafdSChristopher Ferris int rc;
208*a248dafdSChristopher Ferris struct sigaction sig_cleanup_action;
209*a248dafdSChristopher Ferris int opt;
210*a248dafdSChristopher Ferris int index;
211*a248dafdSChristopher Ferris char *deviceName = NULL;
212*a248dafdSChristopher Ferris RMIDevice *device;
213*a248dafdSChristopher Ferris const char *protocol = "HID";
214*a248dafdSChristopher Ferris unsigned char report[256];
215*a248dafdSChristopher Ferris char token[256];
216*a248dafdSChristopher Ferris enum RMIDeviceType deviceType = RMI_DEVICE_TYPE_ANY;
217*a248dafdSChristopher Ferris static struct option long_options[] = {
218*a248dafdSChristopher Ferris {"help", 0, NULL, 'h'},
219*a248dafdSChristopher Ferris {"device", 1, NULL, 'd'},
220*a248dafdSChristopher Ferris {"protocol", 1, NULL, 'p'},
221*a248dafdSChristopher Ferris {"interactive", 0, NULL, 'i'},
222*a248dafdSChristopher Ferris {"read", 1, NULL, 'r'},
223*a248dafdSChristopher Ferris {"write", 1, NULL, 'w'},
224*a248dafdSChristopher Ferris {"firmware-id", 0, NULL, 'f'},
225*a248dafdSChristopher Ferris {"config-id", 0, NULL, 'c'},
226*a248dafdSChristopher Ferris {"props", 0, NULL, 'o'},
227*a248dafdSChristopher Ferris {"attention", 0, NULL, 'a'},
228*a248dafdSChristopher Ferris {"print-functions", 0, NULL, 'm'},
229*a248dafdSChristopher Ferris {"rebind-driver", 0, NULL, 'b'},
230*a248dafdSChristopher Ferris {"device-info", 0, NULL, 'n'},
231*a248dafdSChristopher Ferris {"reset-device", 0, NULL, 'e'},
232*a248dafdSChristopher Ferris {"device-type", 1, NULL, 't'},
233*a248dafdSChristopher Ferris {0, 0, 0, 0},
234*a248dafdSChristopher Ferris };
235*a248dafdSChristopher Ferris enum rmihidtool_cmd cmd = RMIHIDTOOL_CMD_INTERACTIVE;
236*a248dafdSChristopher Ferris unsigned int addr = 0;
237*a248dafdSChristopher Ferris unsigned int len = 0;
238*a248dafdSChristopher Ferris char * data = NULL;
239*a248dafdSChristopher Ferris char * start;
240*a248dafdSChristopher Ferris char * end;
241*a248dafdSChristopher Ferris int i = 0;
242*a248dafdSChristopher Ferris
243*a248dafdSChristopher Ferris memset(&sig_cleanup_action, 0, sizeof(struct sigaction));
244*a248dafdSChristopher Ferris sig_cleanup_action.sa_handler = cleanup;
245*a248dafdSChristopher Ferris sig_cleanup_action.sa_flags = SA_RESTART;
246*a248dafdSChristopher Ferris sigaction(SIGINT, &sig_cleanup_action, NULL);
247*a248dafdSChristopher Ferris
248*a248dafdSChristopher Ferris while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) {
249*a248dafdSChristopher Ferris switch (opt) {
250*a248dafdSChristopher Ferris case 'h':
251*a248dafdSChristopher Ferris print_help(argv[0]);
252*a248dafdSChristopher Ferris return 0;
253*a248dafdSChristopher Ferris case 'p':
254*a248dafdSChristopher Ferris protocol = optarg;
255*a248dafdSChristopher Ferris break;
256*a248dafdSChristopher Ferris case 'd':
257*a248dafdSChristopher Ferris deviceName = optarg;
258*a248dafdSChristopher Ferris break;
259*a248dafdSChristopher Ferris case 'i':
260*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_INTERACTIVE;
261*a248dafdSChristopher Ferris break;
262*a248dafdSChristopher Ferris case 'r':
263*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_READ;
264*a248dafdSChristopher Ferris addr = strtol(optarg, NULL, 0);
265*a248dafdSChristopher Ferris len = strtol(argv[optind++], NULL, 0);
266*a248dafdSChristopher Ferris break;
267*a248dafdSChristopher Ferris case 'w':
268*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_WRITE;
269*a248dafdSChristopher Ferris addr = strtol(optarg, NULL, 0);
270*a248dafdSChristopher Ferris data = argv[optind++];
271*a248dafdSChristopher Ferris break;
272*a248dafdSChristopher Ferris case 'f':
273*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_FW_ID;
274*a248dafdSChristopher Ferris break;
275*a248dafdSChristopher Ferris case 'c':
276*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_CF_ID;
277*a248dafdSChristopher Ferris break;
278*a248dafdSChristopher Ferris case 'o':
279*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_PROPS;
280*a248dafdSChristopher Ferris break;
281*a248dafdSChristopher Ferris case 'a':
282*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_ATTN;
283*a248dafdSChristopher Ferris break;
284*a248dafdSChristopher Ferris case 'm':
285*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_PRINT_FUNCTIONS;
286*a248dafdSChristopher Ferris break;
287*a248dafdSChristopher Ferris case 'b':
288*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_REBIND_DRIVER;
289*a248dafdSChristopher Ferris break;
290*a248dafdSChristopher Ferris case 'n':
291*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_PRINT_DEVICE_INFO;
292*a248dafdSChristopher Ferris break;
293*a248dafdSChristopher Ferris case 'e':
294*a248dafdSChristopher Ferris cmd = RMIHIDTOOL_CMD_RESET_DEVICE;
295*a248dafdSChristopher Ferris break;
296*a248dafdSChristopher Ferris case 't':
297*a248dafdSChristopher Ferris if (!strcasecmp(optarg, "touchpad"))
298*a248dafdSChristopher Ferris deviceType = RMI_DEVICE_TYPE_TOUCHPAD;
299*a248dafdSChristopher Ferris else if (!strcasecmp(optarg, "touchscreen"))
300*a248dafdSChristopher Ferris deviceType = RMI_DEVICE_TYPE_TOUCHSCREEN;
301*a248dafdSChristopher Ferris break;
302*a248dafdSChristopher Ferris default:
303*a248dafdSChristopher Ferris print_help(argv[0]);
304*a248dafdSChristopher Ferris return 0;
305*a248dafdSChristopher Ferris break;
306*a248dafdSChristopher Ferris
307*a248dafdSChristopher Ferris }
308*a248dafdSChristopher Ferris }
309*a248dafdSChristopher Ferris
310*a248dafdSChristopher Ferris if (!strncasecmp("hid", protocol, 3)) {
311*a248dafdSChristopher Ferris device = new HIDDevice();
312*a248dafdSChristopher Ferris } else {
313*a248dafdSChristopher Ferris fprintf(stderr, "Invalid Protocol: %s\n", protocol);
314*a248dafdSChristopher Ferris return -1;
315*a248dafdSChristopher Ferris }
316*a248dafdSChristopher Ferris
317*a248dafdSChristopher Ferris if (optind != argc) {
318*a248dafdSChristopher Ferris print_help(argv[0]);
319*a248dafdSChristopher Ferris return -1;
320*a248dafdSChristopher Ferris }
321*a248dafdSChristopher Ferris
322*a248dafdSChristopher Ferris if (deviceName) {
323*a248dafdSChristopher Ferris rc = device->Open(deviceName);
324*a248dafdSChristopher Ferris if (rc) {
325*a248dafdSChristopher Ferris fprintf(stderr, "%s: failed to initialize rmi device (%d): %s\n", argv[0], errno,
326*a248dafdSChristopher Ferris strerror(errno));
327*a248dafdSChristopher Ferris return 1;
328*a248dafdSChristopher Ferris }
329*a248dafdSChristopher Ferris } else {
330*a248dafdSChristopher Ferris if (!device->FindDevice(deviceType))
331*a248dafdSChristopher Ferris return -1;
332*a248dafdSChristopher Ferris }
333*a248dafdSChristopher Ferris
334*a248dafdSChristopher Ferris g_device = device;
335*a248dafdSChristopher Ferris
336*a248dafdSChristopher Ferris switch (cmd) {
337*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_READ:
338*a248dafdSChristopher Ferris memset(report, 0, sizeof(report));
339*a248dafdSChristopher Ferris rc = device->Read(addr, report, len);
340*a248dafdSChristopher Ferris if (rc < 0)
341*a248dafdSChristopher Ferris fprintf(stderr, "Failed to read report: %d\n", rc);
342*a248dafdSChristopher Ferris
343*a248dafdSChristopher Ferris print_buffer(report, len);
344*a248dafdSChristopher Ferris break;
345*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_WRITE:
346*a248dafdSChristopher Ferris i = 0;
347*a248dafdSChristopher Ferris start = data;
348*a248dafdSChristopher Ferris memset(report, 0, sizeof(report));
349*a248dafdSChristopher Ferris while (find_token(start, token, sizeof(token), &end)) {
350*a248dafdSChristopher Ferris start = end;
351*a248dafdSChristopher Ferris report[i++] = (unsigned char)strtol(token, NULL, 0);
352*a248dafdSChristopher Ferris ++len;
353*a248dafdSChristopher Ferris }
354*a248dafdSChristopher Ferris
355*a248dafdSChristopher Ferris if (device->Write(addr, report, len) < 0) {
356*a248dafdSChristopher Ferris fprintf(stderr, "Failed to Write Report\n");
357*a248dafdSChristopher Ferris return -1;
358*a248dafdSChristopher Ferris }
359*a248dafdSChristopher Ferris break;
360*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_FW_ID:
361*a248dafdSChristopher Ferris device->ScanPDT();
362*a248dafdSChristopher Ferris device->QueryBasicProperties();
363*a248dafdSChristopher Ferris fprintf(stdout, "firmware id: %lu\n", device->GetFirmwareID());
364*a248dafdSChristopher Ferris break;
365*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_CF_ID:
366*a248dafdSChristopher Ferris device->ScanPDT();
367*a248dafdSChristopher Ferris device->QueryBasicProperties();
368*a248dafdSChristopher Ferris fprintf(stdout, "config id: %08lx\n", device->GetConfigID());
369*a248dafdSChristopher Ferris break;
370*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_PROPS:
371*a248dafdSChristopher Ferris device->ScanPDT();
372*a248dafdSChristopher Ferris device->QueryBasicProperties();
373*a248dafdSChristopher Ferris device->PrintProperties();
374*a248dafdSChristopher Ferris break;
375*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_ATTN:
376*a248dafdSChristopher Ferris report_attn = 1;
377*a248dafdSChristopher Ferris while(report_attn) {
378*a248dafdSChristopher Ferris unsigned int bytes = 256;
379*a248dafdSChristopher Ferris rc = device->GetAttentionReport(NULL,
380*a248dafdSChristopher Ferris RMI_INTERUPT_SOURCES_ALL_MASK,
381*a248dafdSChristopher Ferris report, &bytes);
382*a248dafdSChristopher Ferris if (rc > 0) {
383*a248dafdSChristopher Ferris print_buffer(report, bytes);
384*a248dafdSChristopher Ferris fprintf(stdout, "\n");
385*a248dafdSChristopher Ferris }
386*a248dafdSChristopher Ferris }
387*a248dafdSChristopher Ferris break;
388*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_PRINT_FUNCTIONS:
389*a248dafdSChristopher Ferris device->ScanPDT();
390*a248dafdSChristopher Ferris device->PrintFunctions();
391*a248dafdSChristopher Ferris break;
392*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_REBIND_DRIVER:
393*a248dafdSChristopher Ferris device->RebindDriver();
394*a248dafdSChristopher Ferris break;
395*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_PRINT_DEVICE_INFO:
396*a248dafdSChristopher Ferris device->PrintDeviceInfo();
397*a248dafdSChristopher Ferris break;
398*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_RESET_DEVICE:
399*a248dafdSChristopher Ferris device->ScanPDT();
400*a248dafdSChristopher Ferris device->Reset();
401*a248dafdSChristopher Ferris break;
402*a248dafdSChristopher Ferris case RMIHIDTOOL_CMD_INTERACTIVE:
403*a248dafdSChristopher Ferris default:
404*a248dafdSChristopher Ferris interactive(device, report);
405*a248dafdSChristopher Ferris break;
406*a248dafdSChristopher Ferris }
407*a248dafdSChristopher Ferris
408*a248dafdSChristopher Ferris device->Close();
409*a248dafdSChristopher Ferris
410*a248dafdSChristopher Ferris return 0;
411*a248dafdSChristopher Ferris }
412