]> cvs.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/usb.c
There's no painless way to do this, but it needs to be done --
[proxmark3-svn] / client / usb.c
... / ...
CommitLineData
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <stdbool.h>
5#include <unistd.h>
6#include <usb.h>
7#include <strings.h>
8#include <errno.h>
9
10#include "prox.h"
11#include "proxmark3.h"
12
13usb_dev_handle *devh = NULL;
14static unsigned int claimed_iface = 0;
15unsigned char return_on_error = 0;
16unsigned char error_occured = 0;
17
18void SendCommand(UsbCommand *c, bool wantAck) {
19 int ret;
20
21#if 0
22 printf("Sending %d bytes\n", sizeof(UsbCommand));
23#endif
24 ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
25 if (ret<0) {
26 error_occured = 1;
27 if (return_on_error)
28 return;
29
30 fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n",
31 usb_strerror());
32
33 if (devh) {
34 usb_close(devh);
35 devh = NULL;
36 }
37 while(!(devh=OpenProxmark(0))) { sleep(1); }
38 printf(PROXPROMPT);
39 fflush(NULL);
40
41 return;
42 }
43
44 if(wantAck) {
45 UsbCommand ack;
46 ReceiveCommand(&ack);
47 if(ack.cmd != CMD_ACK) {
48 printf("bad ACK\n");
49 exit(-1);
50 }
51 }
52}
53
54int ReceiveCommandP(UsbCommand *c) {
55 int ret;
56
57 bzero(c, sizeof(UsbCommand));
58 ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
59 if (ret<0) {
60 if (ret != -ETIMEDOUT) {
61 error_occured = 1;
62 if (return_on_error)
63 return 0;
64
65 fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n",
66 usb_strerror(), ret);
67
68 if (devh) {
69 usb_close(devh);
70 devh = NULL;
71 }
72 while(!(devh=OpenProxmark(0))) { sleep(1); }
73 printf(PROXPROMPT);
74 fflush(NULL);
75
76 return 0;
77 }
78 } else {
79 if (ret && (ret < sizeof(UsbCommand))) {
80 fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
81 ret, (int)sizeof(UsbCommand));
82 }
83
84#if 0
85 {
86 int i;
87
88 printf("Read %d bytes\n", ret);
89 for (i = 0; i < ret; i++) {
90 printf("0x%02X ", ((unsigned char*)c)[i]);
91 if (!((i+1)%8))
92 printf("\n");
93 }
94 printf("\n");
95 }
96#endif
97 }
98
99 return ret;
100}
101
102void ReceiveCommand(UsbCommand *c) {
103 while(ReceiveCommandP(c)<0) {}
104}
105
106usb_dev_handle* findProxmark(int verbose, unsigned int *iface) {
107 struct usb_bus *busses, *bus;
108 usb_dev_handle *handle = NULL;
109
110 usb_find_busses();
111 usb_find_devices();
112
113 busses = usb_get_busses();
114
115 for (bus = busses; bus; bus = bus->next) {
116 struct usb_device *dev;
117
118 for (dev = bus->devices; dev; dev = dev->next) {
119 struct usb_device_descriptor *desc = &(dev->descriptor);
120
121 if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) {
122 handle = usb_open(dev);
123 if (!handle) {
124 if (verbose)
125 fprintf(stderr, "open failed: %s!\n", usb_strerror());
126 return NULL;
127 }
128
129 *iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
130
131 return handle;
132 }
133 }
134 }
135
136 return NULL;
137}
138
139usb_dev_handle* OpenProxmark(int verbose) {
140 int ret;
141 usb_dev_handle *handle = NULL;
142 unsigned int iface;
143
144#ifndef __APPLE__
145 handle = findProxmark(verbose, &iface);
146 if (!handle)
147 return NULL;
148
149 /* Whatever... */
150 usb_reset(handle);
151#endif
152
153 handle = findProxmark(verbose, &iface);
154 if (!handle)
155 return NULL;
156
157#ifndef __APPLE__
158 /* detach kernel driver first */
159 ret = usb_detach_kernel_driver_np(handle, iface);
160 /* don't complain if no driver attached */
161 if (ret<0 && ret != -61 && verbose)
162 fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror());
163#endif
164 ret = usb_claim_interface(handle, iface);
165 if (ret<0) {
166 if (verbose)
167 fprintf(stderr, "claim failed: %s!\n", usb_strerror());
168 return NULL;
169 }
170
171 claimed_iface = iface;
172 devh = handle;
173 return handle;
174}
175
176void CloseProxmark(void) {
177 usb_release_interface(devh, claimed_iface);
178 usb_close(devh);
179}
Impressum, Datenschutz