removing old commands from cmd-tool
[labortage2013badge.git] / hostware / commandline / main.c
1 /* Name: set-led.c
2  * Project: hid-custom-rq example
3  * Author: Christian Starkjohann
4  * Creation Date: 2008-04-10
5  * Tabsize: 4
6  * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8  * This Revision: $Id: set-led.c 692 2008-11-07 15:07:40Z cs $
9  */
10
11 /*
12 General Description:
13 This is the host-side driver for the custom-class example device. It searches
14 the USB for the LEDControl device and sends the requests understood by this
15 device.
16 This program must be linked with libusb on Unix and libusb-win32 on Windows.
17 See http://libusb.sourceforge.net/ or http://libusb-win32.sourceforge.net/
18 respectively.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <getopt.h>
26 #include <ctype.h>
27 #include <usb.h>        /* this is libusb */
28 #include <arpa/inet.h>
29 #include "hexdump.h"
30 #include "opendevice.h" /* common code moved to separate module */
31
32 #include "../../firmware/requests.h"   /* custom request numbers */
33 #include "../../firmware/usbconfig.h"  /* device's VID/PID and names */
34
35 int safety_question_override=0;
36 int pad=-1;
37
38 char* fname;
39 usb_dev_handle *handle = NULL;
40
41 int8_t hex_to_int(char c) {
42     int8_t r = -1;
43     if (c >= '0' && c <= '9') {
44         r = c - '0';
45     } else {
46         c |= 'a' ^ 'A';
47         if (c >= 'a' && c <= 'f') {
48             r = 10 + c - 'a';
49         }
50     }
51     return r;
52 }
53
54 void press_button(char *param){
55     usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_PRESS_BUTTON, 0, 0, NULL, 0, 5000);
56 }
57
58 void set_dbg(char *hex_string){
59         uint8_t buffer[(strlen(hex_string) + 1) / 2];
60         size_t i = 0, length = 0;
61         int8_t t;
62
63         memset(buffer, 0, (strlen(hex_string) + 1) / 2);
64
65         while (hex_string[i]) {
66             t = hex_to_int(hex_string[i]);
67             if (t == -1){
68                 break;
69             }
70             if (i & 1) {
71                 buffer[length++] |= t;
72             } else {
73                 buffer[length] |= t << 4;
74             }
75         }
76
77         usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_DBG, 0, 0, (char*)buffer, length, 5000);
78 }
79
80 void get_dbg(char *param){
81         uint16_t buffer[256];
82         int cnt;
83         cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_DBG, 0, 0, (char*)buffer, 256, 5000);
84         printf("DBG-Buffer:\n");
85         hexdump_block(stdout, buffer, 0, cnt, 16);
86 }
87
88 void clr_dbg(char *param){
89     usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_CLR_DBG, 0, 0, NULL, 0, 5000);
90 }
91
92 void set_secret(char *hex_string){
93     uint8_t buffer[(strlen(hex_string) + 1) / 2];
94     size_t i = 0, length = 0;
95     int8_t t;
96
97     memset(buffer, 0, (strlen(hex_string) + 1) / 2);
98
99     while (hex_string[i]) {
100         t = hex_to_int(hex_string[i]);
101         if (t == -1){
102             break;
103         }
104         if (i & 1) {
105             buffer[length++] |= t;
106         } else {
107             buffer[length] |= t << 4;
108         }
109     }
110
111     usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_SECRET, length * 8, 0, (char*)buffer, length, 5000);
112 }
113
114 void inc_counter(char *param){
115     usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_INC_COUNTER, 0, 0, NULL, 0, 5000);
116 }
117
118 void get_counter(char *param){
119     uint32_t counter;
120     int cnt;
121     cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_COUNTER, 0, 0, (char*)&counter, 4, 5000);
122     if (cnt == 4) {
123         printf("internal counter = %"PRId32"\n", counter);
124     } else {
125         fprintf(stderr, "Error: reading %d bytes for counter, expecting 4\n", cnt);
126     }
127 }
128
129 void reset_counter(char *param){
130     usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_RESET_COUNTER, 0, 0, NULL, 0, 5000);
131 }
132
133 void get_reset_counter (char *param){
134     uint8_t counter;
135     int cnt;
136     cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_RESET_COUNTER, 0, 0, (char*)&counter, 1, 5000);
137     if (cnt == 1) {
138         printf("internal reset counter = %"PRId8"\n", counter);
139     } else {
140         fprintf(stderr, "Error: reading %d bytes for reset counter, expecting 1\n", cnt);
141     }
142 }
143
144 void get_digits(char *param){
145     uint8_t digits;
146     int cnt;
147     cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_DIGITS, 0, 0, (char*)&digits, 1, 5000);
148     if (cnt == 1) {
149         printf("digits = %"PRId8"\n", digits);
150     } else {
151         fprintf(stderr, "Error: reading %d bytes for reset counter, expecting 1\n", cnt);
152     }
153 }
154
155 void set_digits(char *param){
156     long d;
157     d = strtol(param, NULL, 10);
158     if (d > 9 || d < 6) {
159         fprintf(stderr, "Error: <digits> must be in range 6, 7, 8 or 9\n");
160         return;
161     }
162     usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_SET_DIGITS, d, 0, NULL, 0, 5000);
163 }
164
165 void get_token(char *param){
166     char token[10];
167     int cnt;
168     cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_TOKEN, 0, 0, token, 9, 5000);
169     if (cnt < 9 ) {
170         token[cnt] = '\0';
171         printf("token = %s\n", token);
172     } else {
173         fprintf(stderr, "Error: reading %d bytes for token, expecting max. 9\n", cnt);
174     }
175 }
176
177 void soft_reset(char* param){
178         unsigned delay = 0;
179         if (param) {
180                 sscanf(param, "%i", &delay);
181         }
182         delay &= 0xf;
183         usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_RESET, (int)delay, 0, NULL, 0, 5000);
184 }
185
186 void read_button(char* param){
187         uint8_t v;
188         usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_READ_BUTTON, 0, 0, (char*)&v, 1, 5000);
189         printf("button is %s\n",v?"on":"off");
190 }
191
192 static struct option long_options[] =
193              {
194                /* These options don't set a flag.
195                   We distinguish them by their indices. */
196                {"set-secret",        required_argument, NULL, 's'},
197                {"inc-counter",       no_argument,       NULL, 'i'},
198                {"get-counter",       no_argument,       NULL, 'c'},
199                {"reset-counter",     no_argument,       NULL, 'r'},
200                {"get-reset-counter", no_argument,       NULL, 'q'},
201                {"get-digits",        no_argument,       NULL, 'D'},
202                {"set-digits",        required_argument, NULL, 'd'},
203                {"reset",             optional_argument, NULL, 'R'},
204                {"get-token",         no_argument,       NULL, 't'},
205                {"read-button",       no_argument,       NULL, 'b'},
206                {"press-button",      no_argument,       NULL, 'B'},
207                {"get-dbg",           no_argument,       NULL, 'x'},
208                {"set-dbg",           required_argument, NULL, 'y'},
209                {"clr-dbg",           no_argument,       NULL, 'z'},
210                {0, 0, 0, 0}
211              };
212
213 static void usage(char *name)
214 {
215         char *usage_str =
216         "usage:\n"
217     "    %s <command> <parameter string>\n"
218         "  <command> is one of the following\n"
219         "    -s --set-secret <secret> .... set secret (<secret> is a byte sequence in hex)\n"
220         "    -i --inc-counter ............ increment internal counter\n"
221         "    -c --get-counter ............ get current counter value\n"
222         "    -r --reset-counter .......... reset internal counter to zero\n"
223         "    -q --get-reset-counter....... get the times the counter was reseted\n"
224         "    -D --get-digits ............. get the amount of digits per token\n"
225         "    -d --set-digits <digits>..... set the amount of digits per token (in range 6..9)\n"
226     "    -R --reset[=<delay>] ........ reset the controller with delay (in range 0..9)\n"
227     "    -t --get-token .............. get a token\n\n"
228         "    -b --read-button ............ read status of button\n"
229     "    -B --press-button ........... simulate a button press\n"
230         "    -x --get-dbg ................ get content of the debug register\n"
231     "    -y --set-dbg <data>.......... set content of the debug register (<data> is a byte squence in hex of max. 8 bytes)\n"
232     "    -z --clr-dbg ................ clear the content of the debug register\n"
233
234         " Please note:\n"
235         "   If you use optional parameters you have to use two different way to specify the parameter,\n"
236         "   depending on if you use short or long options.\n"
237         "   Short options: You have to put the parameter directly behind the option letter. Exp: -R6\n"
238         "   Long options: You have to seperate the option from the parameter with '='. Exp: --reset=6\n"
239         ;
240         fprintf(stderr, usage_str, name);
241 }
242
243
244 int main(int argc, char **argv)
245 {
246   const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}; 
247   const unsigned char rawPid[2] = {USB_CFG_DEVICE_ID};
248   char vendor[] = {USB_CFG_VENDOR_NAME, 0};
249   char product[] = {USB_CFG_DEVICE_NAME, 0};
250   int  vid, pid;
251   int  c, option_index;
252   void(*action_fn)(char*) = NULL;
253   char* main_arg = NULL;
254   usb_init();
255   if(argc < 2){   /* we need at least one argument */
256     usage(argv[0]);
257     exit(1);
258   }
259   /* compute VID/PID from usbconfig.h so that there is a central source of information */
260     vid = rawVid[1] * 256 + rawVid[0];
261     pid = rawPid[1] * 256 + rawPid[0];
262     /* The following function is in opendevice.c: */
263     if(usbOpenDevice(&handle, vid, vendor, pid, NULL, NULL, NULL, NULL) != 0){
264         fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
265         exit(1);
266     }
267
268     for (;;) {
269         c = getopt_long(argc, argv, "s:icrqDd:R::tbBxy:z", long_options, &option_index);
270         if (c == -1) {
271                 break;
272         }
273
274         if (action_fn && strchr("sicrqDdRtbBxyz", c)) {
275                 /* action given while already having an action */
276                 usage(argv[0]);
277                 exit(1);
278         }
279
280         if(strchr("sdRy", c)){
281                 main_arg = optarg;
282         }
283 /*
284     "    -s --set-secret <secret> .... set secret (<secret> is a byte sequence in hex)\n"
285     "    -i --inc-counter ............ increment internal counter\n"
286     "    -c --get-counter ............ get current counter value\n"
287     "    -r --reset-counter .......... reset internal counter to zero\n"
288     "    -q --get-reset-counter....... get the times the counter was reseted\n"
289     "    -D --get-digits ............. get the amount of digits per token\n"
290     "    -d --set-digits <digits>..... set the amount of digits per token (in range 6..9)\n"
291     "    -R --reset[=<delay>] ........ reset the controller with delay (in range 0..9)\n"
292     "    -t --get-token .............. get a token\n\n"
293     "    -b --read-button ............ read status of button\n"
294     "    -B --press-button ........... simulate a button press\n"
295     "    -x --get-dbg ................ get content of the debug register\n"
296     "    -y --set-dbg <data>.......... set content of the debug register (<data> is a byte squence in hex of max. 8 bytes)\n"
297     "    -z --clr-dbg ................ clear the content of the debug register\n"
298 */
299         switch (c) {
300         case 's': action_fn = set_secret; break;
301         case 'i': action_fn = inc_counter; break;
302         case 'c': action_fn = get_counter; break;
303         case 'r': action_fn = reset_counter; break;
304         case 'q': action_fn = get_reset_counter; break;
305         case 'D': action_fn = get_digits; break;
306         case 'd': action_fn = set_digits; break;
307         case 'R': action_fn = soft_reset; break;
308         case 't': action_fn = get_token; break;
309         case 'b': action_fn = read_button; break;
310         case 'B': action_fn = press_button; break;
311         case 'y': action_fn = set_dbg; break;
312         case 'x': action_fn = get_dbg; break;
313         case 'z': action_fn = clr_dbg; break;
314         default:
315                 break;
316         }
317     }
318
319     if (!action_fn) {
320         usage(argv[0]);
321         fprintf(stderr, "Error: no action specified\n");
322         return 1;
323     } else {
324         action_fn(main_arg);
325         usb_close(handle);
326         return 0;
327     }
328
329 }