]> git.zerfleddert.de Git - proxmark3-svn/blob - client/hid-flasher/proxusb.c
USB comms: part 2 towards @micolous PR#463 (#595)
[proxmark3-svn] / client / hid-flasher / proxusb.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
3 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
4 //
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
7 // the license.
8 //-----------------------------------------------------------------------------
9 // USB utilities
10 //-----------------------------------------------------------------------------
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdbool.h>
16 #include <unistd.h>
17 #include <usb.h>
18 #include <strings.h>
19 #include <errno.h>
20
21 #include "proxusb.h"
22 #include "proxmark3.h"
23 #include "usb_cmd.h"
24
25 // It seems to be missing for mingw
26 #ifndef ETIMEDOUT
27 #define ETIMEDOUT 116
28 #endif
29
30 usb_dev_handle *devh = NULL;
31 static unsigned int claimed_iface = 0;
32 unsigned char return_on_error = 0;
33 unsigned char error_occured = 0;
34
35 void SendCommand(UsbCommand *c)
36 {
37 int ret;
38
39 #if 0
40 printf("Sending %d bytes\n", sizeof(UsbCommand));
41 #endif
42 ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
43 if (ret<0) {
44 error_occured = 1;
45 if (return_on_error)
46 return;
47
48 fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n",
49 usb_strerror());
50
51 if (devh) {
52 usb_close(devh);
53 devh = NULL;
54 }
55 while(!OpenProxmark(0)) { sleep(1); }
56 printf(PROXPROMPT);
57 fflush(NULL);
58
59 return;
60 }
61 }
62
63 bool ReceiveCommandPoll(UsbCommand *c)
64 {
65 int ret;
66
67 memset(c, 0, sizeof (UsbCommand));
68 ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
69 if (ret<0) {
70 if (ret != -ETIMEDOUT) {
71 error_occured = 1;
72 if (return_on_error)
73 return false;
74
75 fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n",
76 usb_strerror(), ret);
77
78 if (devh) {
79 usb_close(devh);
80 devh = NULL;
81 }
82 while(!OpenProxmark(0)) { sleep(1); }
83 printf(PROXPROMPT);
84 fflush(NULL);
85
86 return false;
87 }
88 } else {
89 if (ret && (ret < sizeof(UsbCommand))) {
90 fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
91 ret, (int)sizeof(UsbCommand));
92 }
93 }
94
95 return ret > 0;
96 }
97
98 void ReceiveCommand(UsbCommand *c)
99 {
100 // printf("%s()\n", __FUNCTION__);
101 int retval = 0;
102 do {
103 retval = ReceiveCommandPoll(c);
104 if (retval != 1) printf("ReceiveCommandPoll returned %d\n", retval);
105 } while(retval<0);
106 // printf("recv %x\n", c->cmd);
107 }
108
109 usb_dev_handle* findProxmark(int verbose, unsigned int *iface)
110 {
111 struct usb_bus *busses, *bus;
112 usb_dev_handle *handle = NULL;
113 struct prox_unit units[50];
114 int iUnit = 0;
115
116 usb_find_busses();
117 usb_find_devices();
118
119 busses = usb_get_busses();
120
121 for (bus = busses; bus; bus = bus->next) {
122 struct usb_device *dev;
123
124 for (dev = bus->devices; dev; dev = dev->next) {
125 struct usb_device_descriptor *desc = &(dev->descriptor);
126
127 if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) {
128 handle = usb_open(dev);
129 if (!handle) {
130 if (verbose)
131 fprintf(stderr, "open fabiled: %s!\n", usb_strerror());
132 //return NULL;
133 continue;
134 }
135 *iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
136
137 struct prox_unit unit = {handle, {0}};
138 usb_get_string_simple(handle, desc->iSerialNumber, unit.serial_number, sizeof(unit.serial_number));
139 units[iUnit++] = unit;
140
141 //return handle;
142 }
143 }
144 }
145
146 if (iUnit > 0) {
147 int iSelection = 0;
148
149 fprintf(stdout, "\nConnected units:\n");
150
151 for (int i = 0; i < iUnit; i++) {
152 struct usb_device * dev = usb_device(units[i].handle);
153 fprintf(stdout, "\t%d. SN: %s [%s/%s]\n", i+1, units[i].serial_number, dev->bus->dirname, dev->filename);
154 }
155 if (iUnit > 1) {
156 while (iSelection < 1 || iSelection > iUnit) {
157 fprintf(stdout, "Which unit do you want to connect to? ");
158 fscanf(stdin, "%d", &iSelection);
159 }
160 }
161 else
162 iSelection = 1;
163 iSelection --;
164
165 for (int i = 0; i < iUnit; i++) {
166 if (iSelection == i) continue;
167 usb_close(units[i].handle);
168 units[i].handle = NULL;
169 }
170
171 return units[iSelection].handle;
172 }
173
174 return NULL;
175 }
176
177 usb_dev_handle* OpenProxmark(int verbose)
178 {
179 int ret;
180 usb_dev_handle *handle = NULL;
181 unsigned int iface;
182
183 handle = findProxmark(verbose, &iface);
184 if (!handle)
185 return NULL;
186
187 #ifdef __linux__
188 /* detach kernel driver first */
189 ret = usb_detach_kernel_driver_np(handle, iface);
190 /* don't complain if no driver attached */
191 if (ret<0 && ret != -61 && verbose)
192 fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror());
193 #endif
194
195 // Needed for Windows. Optional for Mac OS and Linux
196 ret = usb_set_configuration(handle, 1);
197 if (ret < 0) {
198 if (verbose)
199 fprintf(stderr, "configuration set failed: %s!\n", usb_strerror());
200 return NULL;
201 }
202
203 ret = usb_claim_interface(handle, iface);
204 if (ret < 0) {
205 if (verbose)
206 fprintf(stderr, "claim failed: %s!\n", usb_strerror());
207 return NULL;
208 }
209 claimed_iface = iface;
210 devh = handle;
211 return handle;
212 }
213
214 void CloseProxmark(void)
215 {
216 usb_release_interface(devh, claimed_iface);
217 usb_close(devh);
218 devh = NULL;
219 }
Impressum, Datenschutz