Deleted Added
full compact
usbconfig.c (184610) usbconfig.c (185087)
1/* $FreeBSD: head/usr.sbin/usbconfig/usbconfig.c 184610 2008-11-04 02:31:03Z alfred $ */
1/* $FreeBSD: head/usr.sbin/usbconfig/usbconfig.c 185087 2008-11-19 08:56:35Z alfred $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

27#include <stdio.h>
28#include <stdlib.h>
29#include <stdint.h>
30#include <err.h>
31#include <string.h>
32#include <pwd.h>
33#include <grp.h>
34#include <errno.h>
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

27#include <stdio.h>
28#include <stdlib.h>
29#include <stdint.h>
30#include <err.h>
31#include <string.h>
32#include <pwd.h>
33#include <grp.h>
34#include <errno.h>
35#include <ctype.h>
35
36#include <libusb20_desc.h>
37#include <libusb20.h>
38
39#include "dump.h"
40
41struct options {
42 const char *quirkname;
36
37#include <libusb20_desc.h>
38#include <libusb20.h>
39
40#include "dump.h"
41
42struct options {
43 const char *quirkname;
44 void *buffer;
43 gid_t gid;
44 uid_t uid;
45 mode_t mode;
46 uint32_t got_any;
45 gid_t gid;
46 uid_t uid;
47 mode_t mode;
48 uint32_t got_any;
49 struct LIBUSB20_CONTROL_SETUP_DECODED setup;
47 uint16_t bus;
48 uint16_t addr;
49 uint16_t iface;
50 uint16_t vid;
51 uint16_t pid;
52 uint16_t lo_rev; /* inclusive */
53 uint16_t hi_rev; /* inclusive */
50 uint16_t bus;
51 uint16_t addr;
52 uint16_t iface;
53 uint16_t vid;
54 uint16_t pid;
55 uint16_t lo_rev; /* inclusive */
56 uint16_t hi_rev; /* inclusive */
57 uint8_t string_index;
54 uint8_t config_index;
55 uint8_t alt_index;
56 uint8_t got_list:1;
57 uint8_t got_bus:1;
58 uint8_t got_addr:1;
59 uint8_t got_iface:1;
60 uint8_t got_set_config:1;
61 uint8_t got_set_alt:1;

--- 9 unchanged lines hidden (view full) ---

71 uint8_t got_dump_quirk_names:1;
72 uint8_t got_dump_device_desc:1;
73 uint8_t got_dump_curr_config:1;
74 uint8_t got_dump_all_config:1;
75 uint8_t got_dump_info:1;
76 uint8_t got_dump_access:1;
77 uint8_t got_remove_device_quirk:1;
78 uint8_t got_add_device_quirk:1;
58 uint8_t config_index;
59 uint8_t alt_index;
60 uint8_t got_list:1;
61 uint8_t got_bus:1;
62 uint8_t got_addr:1;
63 uint8_t got_iface:1;
64 uint8_t got_set_config:1;
65 uint8_t got_set_alt:1;

--- 9 unchanged lines hidden (view full) ---

75 uint8_t got_dump_quirk_names:1;
76 uint8_t got_dump_device_desc:1;
77 uint8_t got_dump_curr_config:1;
78 uint8_t got_dump_all_config:1;
79 uint8_t got_dump_info:1;
80 uint8_t got_dump_access:1;
81 uint8_t got_remove_device_quirk:1;
82 uint8_t got_add_device_quirk:1;
83 uint8_t got_dump_string:1;
84 uint8_t got_do_request:1;
79};
80
81struct token {
82 const char *name;
83 uint8_t value;
84 uint8_t narg;
85};
86

--- 7 unchanged lines hidden (view full) ---

94 T_SET_PERM,
95 T_ADD_DEVICE_QUIRK,
96 T_REMOVE_DEVICE_QUIRK,
97 T_DUMP_QUIRK_NAMES,
98 T_DUMP_DEVICE_QUIRKS,
99 T_DUMP_DEVICE_DESC,
100 T_DUMP_CURR_CONFIG_DESC,
101 T_DUMP_ALL_CONFIG_DESC,
85};
86
87struct token {
88 const char *name;
89 uint8_t value;
90 uint8_t narg;
91};
92

--- 7 unchanged lines hidden (view full) ---

100 T_SET_PERM,
101 T_ADD_DEVICE_QUIRK,
102 T_REMOVE_DEVICE_QUIRK,
103 T_DUMP_QUIRK_NAMES,
104 T_DUMP_DEVICE_QUIRKS,
105 T_DUMP_DEVICE_DESC,
106 T_DUMP_CURR_CONFIG_DESC,
107 T_DUMP_ALL_CONFIG_DESC,
108 T_DUMP_STRING,
102 T_DUMP_ACCESS,
103 T_DUMP_INFO,
104 T_SUSPEND,
105 T_RESUME,
106 T_POWER_OFF,
107 T_POWER_SAVE,
108 T_POWER_ON,
109 T_RESET,
110 T_LIST,
109 T_DUMP_ACCESS,
110 T_DUMP_INFO,
111 T_SUSPEND,
112 T_RESUME,
113 T_POWER_OFF,
114 T_POWER_SAVE,
115 T_POWER_ON,
116 T_RESET,
117 T_LIST,
118 T_DO_REQUEST,
111};
112
113static struct options options;
114
115static const struct token token[] = {
116 {"-u", T_UNIT, 1},
117 {"-a", T_ADDR, 1},
118 {"-i", T_IFACE, 1},
119 {"set_config", T_SET_CONFIG, 1},
120 {"set_alt", T_SET_ALT, 1},
121 {"set_owner", T_SET_OWNER, 1},
122 {"set_perm", T_SET_PERM, 1},
123 {"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5},
124 {"remove_dev_quirk_vplh", T_REMOVE_DEVICE_QUIRK, 5},
125 {"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
126 {"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
127 {"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
128 {"dump_curr_config_desc", T_DUMP_CURR_CONFIG_DESC, 0},
129 {"dump_all_config_desc", T_DUMP_ALL_CONFIG_DESC, 0},
119};
120
121static struct options options;
122
123static const struct token token[] = {
124 {"-u", T_UNIT, 1},
125 {"-a", T_ADDR, 1},
126 {"-i", T_IFACE, 1},
127 {"set_config", T_SET_CONFIG, 1},
128 {"set_alt", T_SET_ALT, 1},
129 {"set_owner", T_SET_OWNER, 1},
130 {"set_perm", T_SET_PERM, 1},
131 {"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5},
132 {"remove_dev_quirk_vplh", T_REMOVE_DEVICE_QUIRK, 5},
133 {"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
134 {"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
135 {"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
136 {"dump_curr_config_desc", T_DUMP_CURR_CONFIG_DESC, 0},
137 {"dump_all_config_desc", T_DUMP_ALL_CONFIG_DESC, 0},
138 {"dump_string", T_DUMP_STRING, 1},
130 {"dump_access", T_DUMP_ACCESS, 0},
131 {"dump_info", T_DUMP_INFO, 0},
132 {"suspend", T_SUSPEND, 0},
133 {"resume", T_RESUME, 0},
134 {"power_off", T_POWER_OFF, 0},
135 {"power_save", T_POWER_SAVE, 0},
136 {"power_on", T_POWER_ON, 0},
137 {"reset", T_RESET, 0},
138 {"list", T_LIST, 0},
139 {"dump_access", T_DUMP_ACCESS, 0},
140 {"dump_info", T_DUMP_INFO, 0},
141 {"suspend", T_SUSPEND, 0},
142 {"resume", T_RESUME, 0},
143 {"power_off", T_POWER_OFF, 0},
144 {"power_save", T_POWER_SAVE, 0},
145 {"power_on", T_POWER_ON, 0},
146 {"reset", T_RESET, 0},
147 {"list", T_LIST, 0},
148 {"do_request", T_DO_REQUEST, 5},
139};
140
141static void
142be_dev_remove_quirk(struct libusb20_backend *pbe,
143 uint16_t vid, uint16_t pid, uint16_t lorev, uint16_t hirev,
144 const char *str)
145{
146 struct libusb20_quirk q;
149};
150
151static void
152be_dev_remove_quirk(struct libusb20_backend *pbe,
153 uint16_t vid, uint16_t pid, uint16_t lorev, uint16_t hirev,
154 const char *str)
155{
156 struct libusb20_quirk q;
147 int err;
157 int error;
148
149 memset(&q, 0, sizeof(q));
150
151 q.vid = vid;
152 q.pid = pid;
153 q.bcdDeviceLow = lorev;
154 q.bcdDeviceHigh = hirev;
155 strlcpy(q.quirkname, str, sizeof(q.quirkname));
156
158
159 memset(&q, 0, sizeof(q));
160
161 q.vid = vid;
162 q.pid = pid;
163 q.bcdDeviceLow = lorev;
164 q.bcdDeviceHigh = hirev;
165 strlcpy(q.quirkname, str, sizeof(q.quirkname));
166
157 err = libusb20_be_remove_dev_quirk(pbe, &q);
158 if (err) {
167 error = libusb20_be_remove_dev_quirk(pbe, &q);
168 if (error) {
159 printf("Removing quirk '%s' failed, continuing.\n", str);
160 }
161 return;
162}
163
164static void
165be_dev_add_quirk(struct libusb20_backend *pbe,
166 uint16_t vid, uint16_t pid, uint16_t lorev, uint16_t hirev,
167 const char *str)
168{
169 struct libusb20_quirk q;
169 printf("Removing quirk '%s' failed, continuing.\n", str);
170 }
171 return;
172}
173
174static void
175be_dev_add_quirk(struct libusb20_backend *pbe,
176 uint16_t vid, uint16_t pid, uint16_t lorev, uint16_t hirev,
177 const char *str)
178{
179 struct libusb20_quirk q;
170 int err;
180 int error;
171
172 memset(&q, 0, sizeof(q));
173
174 q.vid = vid;
175 q.pid = pid;
176 q.bcdDeviceLow = lorev;
177 q.bcdDeviceHigh = hirev;
178 strlcpy(q.quirkname, str, sizeof(q.quirkname));
179
181
182 memset(&q, 0, sizeof(q));
183
184 q.vid = vid;
185 q.pid = pid;
186 q.bcdDeviceLow = lorev;
187 q.bcdDeviceHigh = hirev;
188 strlcpy(q.quirkname, str, sizeof(q.quirkname));
189
180 err = libusb20_be_add_dev_quirk(pbe, &q);
181 if (err) {
190 error = libusb20_be_add_dev_quirk(pbe, &q);
191 if (error) {
182 printf("Adding quirk '%s' failed, continuing.\n", str);
183 }
184 return;
185}
186
187static uint8_t
188get_token(const char *str, uint8_t narg)
189{
190 uint8_t n;
191
192 for (n = 0; n != (sizeof(token) / sizeof(token[0])); n++) {
193 if (strcasecmp(str, token[n].name) == 0) {
194 if (token[n].narg > narg) {
192 printf("Adding quirk '%s' failed, continuing.\n", str);
193 }
194 return;
195}
196
197static uint8_t
198get_token(const char *str, uint8_t narg)
199{
200 uint8_t n;
201
202 for (n = 0; n != (sizeof(token) / sizeof(token[0])); n++) {
203 if (strcasecmp(str, token[n].name) == 0) {
204 if (token[n].narg > narg) {
195 /* to little arguments */
205 /* too few arguments */
196 break;
197 }
198 return (token[n].value);
199 }
200 }
201 return (0 - 1);
202}
203

--- 57 unchanged lines hidden (view full) ---

261
262static void
263usage(void)
264{
265 printf(""
266 "usbconfig - configure the USB subsystem" "\n"
267 "usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
268 "commands:" "\n"
206 break;
207 }
208 return (token[n].value);
209 }
210 }
211 return (0 - 1);
212}
213

--- 57 unchanged lines hidden (view full) ---

271
272static void
273usage(void)
274{
275 printf(""
276 "usbconfig - configure the USB subsystem" "\n"
277 "usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
278 "commands:" "\n"
269 " set_config <num>" "\n"
270 " set_alt <altno>" "\n"
279 " set_config <cfg_index>" "\n"
280 " set_alt <alt_index>" "\n"
271 " set_owner <user:group>" "\n"
272 " set_perm <mode>" "\n"
273 " add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
274 " remove_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
275 " dump_quirk_names" "\n"
276 " dump_device_quirks" "\n"
277 " dump_device_desc" "\n"
278 " dump_curr_config_desc" "\n"
279 " dump_all_config_desc" "\n"
281 " set_owner <user:group>" "\n"
282 " set_perm <mode>" "\n"
283 " add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
284 " remove_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
285 " dump_quirk_names" "\n"
286 " dump_device_quirks" "\n"
287 " dump_device_desc" "\n"
288 " dump_curr_config_desc" "\n"
289 " dump_all_config_desc" "\n"
290 " dump_string <index>" "\n"
280 " dump_access" "\n"
281 " dump_info" "\n"
282 " suspend" "\n"
283 " resume" "\n"
284 " power_off" "\n"
285 " power_save" "\n"
286 " power_on" "\n"
287 " reset" "\n"
288 " list" "\n"
291 " dump_access" "\n"
292 " dump_info" "\n"
293 " suspend" "\n"
294 " resume" "\n"
295 " power_off" "\n"
296 " power_save" "\n"
297 " power_on" "\n"
298 " reset" "\n"
299 " list" "\n"
300 " do_request <bmReqTyp> <bReq> <wVal> <wIdx> <wLen> <data...>" "\n"
289 );
290 exit(1);
291}
292
293static void
294reset_options(struct options *opt)
295{
301 );
302 exit(1);
303}
304
305static void
306reset_options(struct options *opt)
307{
308 if (opt->buffer)
309 free(opt->buffer);
296 memset(opt, 0, sizeof(*opt));
297 return;
298}
299
300static void
301flush_command(struct libusb20_backend *pbe, struct options *opt)
302{
303 struct libusb20_device *pdev = NULL;

--- 109 unchanged lines hidden (view full) ---

413 err(1, "setting mode failed\n");
414 }
415 }
416 }
417
418 if (libusb20_dev_open(pdev, 0)) {
419 err(1, "could not open device");
420 }
310 memset(opt, 0, sizeof(*opt));
311 return;
312}
313
314static void
315flush_command(struct libusb20_backend *pbe, struct options *opt)
316{
317 struct libusb20_device *pdev = NULL;

--- 109 unchanged lines hidden (view full) ---

427 err(1, "setting mode failed\n");
428 }
429 }
430 }
431
432 if (libusb20_dev_open(pdev, 0)) {
433 err(1, "could not open device");
434 }
435 if (opt->got_dump_string) {
436 char *pbuf;
437
438 pbuf = malloc(256);
439 if (pbuf == NULL) {
440 err(1, "out of memory");
441 }
442 if (libusb20_dev_req_string_simple_sync(pdev,
443 opt->string_index, pbuf, 256)) {
444 printf("STRING_0x%02x = <read error>\n",
445 opt->string_index);
446 } else {
447 printf("STRING_0x%02x = <%s>\n",
448 opt->string_index, pbuf);
449 }
450 free(pbuf);
451 }
452 if (opt->got_do_request) {
453 uint16_t actlen;
454 uint16_t t;
455
456 if (libusb20_dev_request_sync(pdev, &opt->setup,
457 opt->buffer, &actlen, 5000 /* 5 seconds */ , 0)) {
458 printf("REQUEST = <ERROR>\n");
459 } else if (!(opt->setup.bmRequestType &
460 LIBUSB20_ENDPOINT_IN)) {
461 printf("REQUEST = <OK>\n");
462 } else {
463 t = actlen;
464 printf("REQUEST = <");
465 for (t = 0; t != actlen; t++) {
466 printf("0x%02x%s",
467 ((uint8_t *)opt->buffer)[t],
468 (t == (actlen - 1)) ? "" : " ");
469 }
470 printf("><");
471 for (t = 0; t != actlen; t++) {
472 char c;
473
474 c = ((uint8_t *)opt->buffer)[t];
475 if ((c != '<') &&
476 (c != '>') && isprint(c)) {
477 putchar(c);
478 }
479 }
480 printf(">\n");
481 }
482 }
421 if (opt->got_set_config) {
422 if (libusb20_dev_set_config_index(pdev,
423 opt->config_index)) {
424 err(1, "could not set config index");
425 }
426 }
427 if (opt->got_set_alt) {
483 if (opt->got_set_config) {
484 if (libusb20_dev_set_config_index(pdev,
485 opt->config_index)) {
486 err(1, "could not set config index");
487 }
488 }
489 if (opt->got_set_alt) {
428 if (libusb20_dev_set_alt_index(pdev, opt->iface, opt->alt_index)) {
490 if (libusb20_dev_set_alt_index(pdev, opt->iface,
491 opt->alt_index)) {
429 err(1, "could not set alternate setting");
430 }
431 }
432 if (opt->got_reset) {
433 if (libusb20_dev_reset(pdev)) {
434 err(1, "could not reset device");
435 }
436 }
437 if (opt->got_suspend) {
492 err(1, "could not set alternate setting");
493 }
494 }
495 if (opt->got_reset) {
496 if (libusb20_dev_reset(pdev)) {
497 err(1, "could not reset device");
498 }
499 }
500 if (opt->got_suspend) {
438 if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SUSPEND)) {
501 if (libusb20_dev_set_power_mode(pdev,
502 LIBUSB20_POWER_SUSPEND)) {
439 err(1, "could not set suspend");
440 }
441 }
442 if (opt->got_resume) {
503 err(1, "could not set suspend");
504 }
505 }
506 if (opt->got_resume) {
443 if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_RESUME)) {
507 if (libusb20_dev_set_power_mode(pdev,
508 LIBUSB20_POWER_RESUME)) {
444 err(1, "could not set resume");
445 }
446 }
447 if (opt->got_power_off) {
509 err(1, "could not set resume");
510 }
511 }
512 if (opt->got_power_off) {
448 if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_OFF)) {
513 if (libusb20_dev_set_power_mode(pdev,
514 LIBUSB20_POWER_OFF)) {
449 err(1, "could not set power OFF");
450 }
451 }
452 if (opt->got_power_save) {
515 err(1, "could not set power OFF");
516 }
517 }
518 if (opt->got_power_save) {
453 if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SAVE)) {
519 if (libusb20_dev_set_power_mode(pdev,
520 LIBUSB20_POWER_SAVE)) {
454 err(1, "could not set power SAVE");
455 }
456 }
457 if (opt->got_power_on) {
521 err(1, "could not set power SAVE");
522 }
523 }
524 if (opt->got_power_on) {
458 if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_ON)) {
525 if (libusb20_dev_set_power_mode(pdev,
526 LIBUSB20_POWER_ON)) {
459 err(1, "could not set power ON");
460 }
461 }
462 dump_any =
463 (opt->got_dump_device_desc ||
464 opt->got_dump_curr_config ||
465 opt->got_dump_all_config ||
466 opt->got_dump_info ||

--- 112 unchanged lines hidden (view full) ---

579 n++;
580 break;
581 case T_IFACE:
582 opt->iface = num_id(argv[n + 1], "iface");
583 opt->got_iface = 1;
584 n++;
585 break;
586 case T_SET_CONFIG:
527 err(1, "could not set power ON");
528 }
529 }
530 dump_any =
531 (opt->got_dump_device_desc ||
532 opt->got_dump_curr_config ||
533 opt->got_dump_all_config ||
534 opt->got_dump_info ||

--- 112 unchanged lines hidden (view full) ---

647 n++;
648 break;
649 case T_IFACE:
650 opt->iface = num_id(argv[n + 1], "iface");
651 opt->got_iface = 1;
652 n++;
653 break;
654 case T_SET_CONFIG:
587 opt->config_index = num_id(argv[n + 1], "confindex");
655 opt->config_index = num_id(argv[n + 1], "cfg_index");
588 opt->got_set_config = 1;
589 opt->got_any++;
590 n++;
591 break;
592 case T_SET_ALT:
656 opt->got_set_config = 1;
657 opt->got_any++;
658 n++;
659 break;
660 case T_SET_ALT:
593 opt->alt_index = num_id(argv[n + 1], "confindex");
661 opt->alt_index = num_id(argv[n + 1], "cfg_index");
594 opt->got_set_alt = 1;
595 opt->got_any++;
596 n++;
597 break;
598 case T_SET_OWNER:
599 cp = argv[n + 1];
600 cp = strchr(cp, ':');
601 if (cp == NULL) {

--- 23 unchanged lines hidden (view full) ---

625 case T_DUMP_ALL_CONFIG_DESC:
626 opt->got_dump_all_config = 1;
627 opt->got_any++;
628 break;
629 case T_DUMP_INFO:
630 opt->got_dump_info = 1;
631 opt->got_any++;
632 break;
662 opt->got_set_alt = 1;
663 opt->got_any++;
664 n++;
665 break;
666 case T_SET_OWNER:
667 cp = argv[n + 1];
668 cp = strchr(cp, ':');
669 if (cp == NULL) {

--- 23 unchanged lines hidden (view full) ---

693 case T_DUMP_ALL_CONFIG_DESC:
694 opt->got_dump_all_config = 1;
695 opt->got_any++;
696 break;
697 case T_DUMP_INFO:
698 opt->got_dump_info = 1;
699 opt->got_any++;
700 break;
701 case T_DUMP_STRING:
702 if (opt->got_dump_string) {
703 flush_command(pbe, opt);
704 }
705 opt->string_index = num_id(argv[n + 1], "str_index");
706 opt->got_dump_string = 1;
707 opt->got_any++;
708 n++;
709 break;
633 case T_DUMP_ACCESS:
634 opt->got_dump_access = 1;
710 case T_DUMP_ACCESS:
711 opt->got_dump_access = 1;
635 opt->got_any++;
712 opt->got_any += 2;
636 break;
637 case T_SUSPEND:
638 opt->got_suspend = 1;
639 opt->got_any++;
640 break;
641 case T_RESUME:
642 opt->got_resume = 1;
643 opt->got_any++;

--- 13 unchanged lines hidden (view full) ---

657 case T_RESET:
658 opt->got_reset = 1;
659 opt->got_any++;
660 break;
661 case T_LIST:
662 opt->got_list = 1;
663 opt->got_any++;
664 break;
713 break;
714 case T_SUSPEND:
715 opt->got_suspend = 1;
716 opt->got_any++;
717 break;
718 case T_RESUME:
719 opt->got_resume = 1;
720 opt->got_any++;

--- 13 unchanged lines hidden (view full) ---

734 case T_RESET:
735 opt->got_reset = 1;
736 opt->got_any++;
737 break;
738 case T_LIST:
739 opt->got_list = 1;
740 opt->got_any++;
741 break;
742 case T_DO_REQUEST:
743 if (opt->got_do_request) {
744 flush_command(pbe, opt);
745 }
746 LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
747 opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
748 opt->setup.bRequest = num_id(argv[n + 2], "bReq");
749 opt->setup.wValue = num_id(argv[n + 3], "wVal");
750 opt->setup.wIndex = num_id(argv[n + 4], "wIndex");
751 opt->setup.wLength = num_id(argv[n + 5], "wLen");
752 if (opt->setup.wLength != 0) {
753 opt->buffer = malloc(opt->setup.wLength);
754 } else {
755 opt->buffer = NULL;
756 }
757
758 n += 5;
759
760 if (!(opt->setup.bmRequestType &
761 LIBUSB20_ENDPOINT_IN)) {
762 /* copy in data */
763 t = (argc - n - 1);
764 if (t < opt->setup.wLength) {
765 err(1, "request data missing");
766 }
767 t = opt->setup.wLength;
768 while (t--) {
769 ((uint8_t *)opt->buffer)[t] =
770 num_id(argv[n + t + 1], "req_data");
771 }
772 n += opt->setup.wLength;
773 }
774 opt->got_do_request = 1;
775 opt->got_any++;
776 break;
665 default:
666 usage();
667 break;
668 }
669 }
670 if (opt->got_any) {
671 /* flush out last command */
672 flush_command(pbe, opt);
673 } else {
674 /* list all the devices */
675 opt->got_list = 1;
676 opt->got_any++;
677 flush_command(pbe, opt);
678 }
679 /* release data */
680 libusb20_be_free(pbe);
681
682 return (0);
683}
777 default:
778 usage();
779 break;
780 }
781 }
782 if (opt->got_any) {
783 /* flush out last command */
784 flush_command(pbe, opt);
785 } else {
786 /* list all the devices */
787 opt->got_list = 1;
788 opt->got_any++;
789 flush_command(pbe, opt);
790 }
791 /* release data */
792 libusb20_be_free(pbe);
793
794 return (0);
795}