blob: 69eadb6dbc33380bd1dcb55aac57f0bf5a528b1b [file] [log] [blame]
Andrew Duggan4e811252014-04-03 15:17:57 -07001#include <stdio.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <errno.h>
6#include <string.h>
7#include <unistd.h>
8#include <sys/ioctl.h>
9#include <sys/select.h>
Andrew Duggan63078d52014-04-08 11:20:15 -070010#include <getopt.h>
Andrew Duggan4e811252014-04-03 15:17:57 -070011
12#include <linux/types.h>
13#include <linux/input.h>
14#include <linux/hidraw.h>
15#include <signal.h>
16#include <stdlib.h>
17
18#include "hiddevice.h"
19
Andrew Duggan63078d52014-04-08 11:20:15 -070020#define RMI4UPDATE_GETOPTS "hp:"
21
Andrew Duggan4e811252014-04-03 15:17:57 -070022static int report_attn = 0;
Andrew Duggan63078d52014-04-08 11:20:15 -070023static RMIDevice * g_device = NULL;
24
25void printArgsHelp(const char *prog_name)
26{
27 fprintf(stdout, "Usage: %s [OPTIONS] DEVICEFILE FIRMWAREFILE\n", prog_name);
28 fprintf(stdout, "\t-h, --help\tPrint this message\n");
29 fprintf(stdout, "\t-p, --protocol [protocol]\tSet which transport prototocl to use.\n");
30}
Andrew Duggan4e811252014-04-03 15:17:57 -070031
32void print_help()
33{
34 fprintf(stdout, "Commands:\n");
35 fprintf(stdout, "s [0,1,2]: Set RMIMode\n");
36 fprintf(stdout, "r address size: read size bytes from address\n");
37 fprintf(stdout, "w address { values }: write bytes to address\n");
38 fprintf(stdout, "a: Wait for attention\n");
39 fprintf(stdout, "q: quit\n");
40}
41
42int find_token(char * input, char * result, char ** endpp)
43{
44 int i = 0;
45 char * start = input;
46 char * end;
47
48 while (input[i] == ' ') {
49 ++start;
50 ++i;
51 }
52
53 while (input[i] != '\0') {
54 ++i;
55 if (input[i] == ' ') {
56 break;
57 }
58 }
59 end = &input[i];
60
61 if (start == end) {
62 return 0;
63 }
64
65 *endpp = end;
66 strncpy(result, start, end - start);
67 result[end - start + 1] = '\0';
68
69 return 1;
70}
71
Andrew Duggan63078d52014-04-08 11:20:15 -070072int process(RMIDevice * device, char * input)
Andrew Duggan4e811252014-04-03 15:17:57 -070073{
74 unsigned char report[256];
75 char token[256];
76 char * start;
77 char * end;
78 int rc;
79
80 memset(token, 0, 256);
81
82 if (input[0] == 's') {
83 start = input + 2;
84 find_token(start, token, &end);
85 int mode = strtol(token, NULL, 0);
86 if (mode >= 0 && mode <= 2) {
87 if (device->SetMode(mode)) {
88 fprintf(stderr, "Set RMI Mode to: %d\n", mode);
89 } else {
90 fprintf(stderr, "Set RMI Mode FAILED!\n");
91 return -1;
92 }
93 }
94 } else if (input[0] == 'r') {
95 start = input + 2;
96 find_token(start, token, &end);
97 start = end + 1;
98 int addr = strtol(token, NULL, 0);
99 find_token(start, token, &end);
100 start = end + 1;
101 int len = strtol(token, NULL, 0);
102 fprintf(stdout, "Address = 0x%02x Length = %d\n", addr, len);
103
104 memset(report, 0, sizeof(report));
105 rc = device->Read(addr, report, len);
106 if (rc < 0)
107 fprintf(stderr, "Failed to read report: %d\n", rc);
108
109 fprintf(stdout, "Data:\n");
110 for (int i = 0; i < len; ++i) {
111 fprintf(stdout, "0x%02X ", report[i]);
112 if (i % 8 == 7) {
113 fprintf(stdout, "\n");
114 }
115 }
116 fprintf(stdout, "\n");
117 } else if (input[0] == 'w') {
118 int index = 0;
119 start = input + 2;
120 find_token(start, token, &end);
121 start = end + 1;
122 int addr = strtol(token, NULL, 0);
123 int len = 0;
124
125 while (find_token(start, token, &end)) {
126 start = end + 1;
127 report[index++] = (unsigned char)strtol(token, NULL, 0);
128 ++len;
129 }
130
131 memset(report, 0, sizeof(report));
132
133 if (device->Write(addr, report, len) < 0) {
134 fprintf(stderr, "Failed to Write Report\n");
135 return -1;
136 }
137 } else if (input[0] == 'a') {
138 report_attn = 1;
139 while(report_attn) {
140 int bytes = 256;
141 device->GetAttentionReport(NULL, NULL, report, &bytes);
142 fprintf(stdout, "Data:\n");
143 for (int i = 0; i < bytes; ++i) {
144 fprintf(stdout, "0x%02X ", report[i]);
145 if (i % 8 == 7) {
146 fprintf(stdout, "\n");
147 }
148 }
149 fprintf(stdout, "\n\n");
150 }
151 } else if (input[0] == 'q') {
152 return 1;
153 } else {
154 print_help();
155 }
156 return 0;
157}
158
159static void cleanup(int status)
160{
161 if (report_attn) {
162 report_attn = 0;
163 if (g_device)
164 g_device->Cancel();
165 } else {
166 exit(0);
167 }
168}
169
170int main(int argc, char ** argv)
171{
172 int rc;
173 struct sigaction sig_cleanup_action;
Andrew Duggan63078d52014-04-08 11:20:15 -0700174 int opt;
175 int index;
176 RMIDevice *device;
177 const char *protocol = "HID";
178 static struct option long_options[] = {
179 {"help", 0, NULL, 'h'},
180 {"protocol", 1, NULL, 'p'},
181 {0, 0, 0, 0},
182 };
Andrew Duggan4e811252014-04-03 15:17:57 -0700183
184 memset(&sig_cleanup_action, 0, sizeof(struct sigaction));
185 sig_cleanup_action.sa_handler = cleanup;
186 sig_cleanup_action.sa_flags = SA_RESTART;
187 sigaction(SIGINT, &sig_cleanup_action, NULL);
188
Andrew Duggan63078d52014-04-08 11:20:15 -0700189 while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) {
190 switch (opt) {
191 case 'h':
192 printArgsHelp(argv[0]);
193 return 0;
194 case 'p':
195 protocol = optarg;
196 break;
197 default:
198 break;
199
200 }
201 }
202
203 if (!strncasecmp("hid", protocol, 3)) {
204 device = new HIDDevice();
205 } else {
206 fprintf(stderr, "Invalid Protocol: %s\n", protocol);
207 return -1;
208 }
209
210 rc = device->Open(argv[optind++]);
Andrew Duggan4e811252014-04-03 15:17:57 -0700211 if (rc) {
Andrew Duggan63078d52014-04-08 11:20:15 -0700212 fprintf(stderr, "%s: failed to initialize rmi device (%d): %s\n", argv[0], errno,
213 strerror(errno));
Andrew Duggan4e811252014-04-03 15:17:57 -0700214 return 1;
215 }
216
Andrew Duggan63078d52014-04-08 11:20:15 -0700217 device->ScanPDT();
218 device->QueryBasicProperties();
219 device->PrintProperties();
Andrew Duggan4e811252014-04-03 15:17:57 -0700220
Andrew Duggan63078d52014-04-08 11:20:15 -0700221 g_device = device;
Andrew Duggan4e811252014-04-03 15:17:57 -0700222
223 fprintf(stdout, "\n");
224 for (;;) {
225 fprintf(stdout, "\n");
226 print_help();
227 char buf[256];
228
229 if (fgets(buf, 256, stdin)) {
Andrew Duggan63078d52014-04-08 11:20:15 -0700230 if (process(device, buf) == 1)
Andrew Duggan4e811252014-04-03 15:17:57 -0700231 break;
232 }
233 }
234
Andrew Duggan63078d52014-04-08 11:20:15 -0700235 device->Close();
Andrew Duggan4e811252014-04-03 15:17:57 -0700236
237 return 0;
238}