/
libhid.c
274 lines (244 loc) · 9.45 KB
/
libhid.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#include <hid.h>
#include <stdio.h>
#include <string.h>
/* Unchanged constants */
#define EP_INTERRUPT_IN 0x81
#define PATHLEN 1
#define PATHIN 0xff000001
/* Prints out the hex on screen */
static void printHex(const void *data, int length)
{
const unsigned char *byte = data;
while (length>0)
{
length--;
printf("%.2x ", *byte);
byte++;
}
}
static void RFIDCommunication(hid_return ret, HIDInterface** const hid)
{
int const PATH_IN[] = { PATHIN };
unsigned int SEND_PACKET_LEN1 = 3;
unsigned int REPLY_PACKET_LENGTH1 = 3;
printf("\n/* * * * * * * * BEGIN COMMUNICATION WITH RFID DEVICE * * * * * * * */");
// SET ANTENNA POWER
char PACKET1[] = { 0xC0, 0x03, 0x12 };
ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET1, SEND_PACKET_LEN1);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
} else {
printf("\n\n----->First sent: \n");
printHex(PACKET1, SEND_PACKET_LEN1);
}
char reply1[REPLY_PACKET_LENGTH1+1];
ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply1, REPLY_PACKET_LENGTH1, 100);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "interrupt read failed with return code %d\n", ret);
} else {
printf("\n\n----->First reply:\n");
printHex(reply1, REPLY_PACKET_LENGTH1);
}
// TAG INVENTORY OPERATION
// XXX: returns EPC Data
unsigned int SEND_PACKET_LEN2 = 3;
unsigned int REPLY_PACKET_LENGTH2 = 64;
char PACKET2[] = { 0x31, 0x03, 0x01 };
ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET2, SEND_PACKET_LEN2);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
} else {
printf("\n\n----->Second sent:\n");
printHex(PACKET2, SEND_PACKET_LEN2);
}
char reply2[REPLY_PACKET_LENGTH2+1];
ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply2, REPLY_PACKET_LENGTH2, 100);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "interrupt read failed with return code %d\n", ret);
} else {
printf("\n\n----->Second reply:\n");
printHex(reply2, REPLY_PACKET_LENGTH2);
}
// NEXT TAG
//unsigned int SEND_PACKET_LEN3 = 3;
//unsigned int REPLY_PACKET_LENGTH3 = 64;
//char PACKET3[] = { 0x31, 0x03, 0x02 };
//ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET3, SEND_PACKET_LEN3);
//if (ret != HID_RET_SUCCESS) {
// fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
//} else {
// printf("\n\n----->Third sent: \n");
// printHex(PACKET3, SEND_PACKET_LEN3);
//}
//char reply3[REPLY_PACKET_LENGTH3+1];
//ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply3, REPLY_PACKET_LENGTH3, 100);
//if (ret != HID_RET_SUCCESS) {
// fprintf(stderr, "interrupt read failed with return code %d\n", ret);
//} else {
// printf("\n\n----->Third reply: \n", reply3);
// printHex(reply3, REPLY_PACKET_LENGTH3);
//}
// TAG SELECT OPERATION
unsigned int SEND_PACKET_LEN4 = 15;
unsigned int REPLY_PACKET_LENGTH4 = 3;
char PACKET4[] = { 0x33, 0x0F, 0x0C, 0xCF, 0xFA, 0x04, 0x9C, 0x53, 0xE0, 0xC9, 0x7E, 0x13, 0x77, 0xFB, 0x97 };
ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET4, SEND_PACKET_LEN4);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
} else {
printf("\n\n----->Fourth sent: \n");
printHex(PACKET4, SEND_PACKET_LEN4);
}
char reply4[REPLY_PACKET_LENGTH4+1];
ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply4, REPLY_PACKET_LENGTH4, 100);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "interrupt read failed with return code %d\n", ret);
} else {
printf("\n\n----->Fourth reply: \n", reply4);
printHex(reply4, REPLY_PACKET_LENGTH4);
}
// TAG READ USER MEMORY OPERATION
unsigned int SEND_PACKET_LEN5 = 9;
unsigned int REPLY_PACKET_LENGTH5 = 64;
char PACKET5[] = { 0x37, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET5, SEND_PACKET_LEN5);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
} else {
printf("\n\n----->Fifth sent: \n");
printHex(PACKET5, SEND_PACKET_LEN5);
}
char reply5[REPLY_PACKET_LENGTH5+1];
ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply5, REPLY_PACKET_LENGTH5, 100);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "interrupt read failed with return code %d\n", ret);
} else {
printf("\n\n----->Fifth reply: \n", reply5);
printHex(reply5, REPLY_PACKET_LENGTH5);
}
// WRITE TO USER MEMORY
signed int SEND_PACKET_LEN6 = 11;
unsigned int REPLY_PACKET_LENGTH6 = 4;
char PACKET6[] = { 0x35, 0x0B, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10 };
ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET6, SEND_PACKET_LEN6);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
} else {
printf("\n\n----->write to user memory: \n");
printHex(PACKET6, SEND_PACKET_LEN6);
}
char reply6[REPLY_PACKET_LENGTH6+1];
ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply6, REPLY_PACKET_LENGTH6, 100);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "interrupt read failed with return code %d\n", ret);
} else {
printf("\n\n----->user memory sent\n", reply6);
printHex(reply6, REPLY_PACKET_LENGTH6);
}
// TAG READ USER MEMORY OPERATION
//unsigned int SEND_PACKET_LEN7 = 9;
//unsigned int REPLY_PACKET_LENGTH7 = 4;
//char PACKET7[] = { 0x37, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
//ret = hid_set_output_report(*hid, PATH_IN, PATHLEN, PACKET7, SEND_PACKET_LEN7);
//if (ret != HID_RET_SUCCESS) {
// fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
//} else {
// printf("\n\n----->Fifth sent: \n");
// printHex(PACKET7, SEND_PACKET_LEN7);
//}
//char reply7[REPLY_PACKET_LENGTH7+1];
//ret = hid_interrupt_read(*hid, EP_INTERRUPT_IN, reply7, REPLY_PACKET_LENGTH7, 100);
//if (ret != HID_RET_SUCCESS) {
// fprintf(stderr, "interrupt read failed with return code %d\n", ret);
//} else {
// printf("\n\n----->Fifth reply: \n", reply7);
// printHex(reply7, REPLY_PACKET_LENGTH7);
//}
}
int main(int argc, char *argv[])
{
HIDInterface* hid;
int iface_num = 0;
hid_return ret;
unsigned short vendor_id = 0x1325;
unsigned short product_id = 0xc029;
char *vendor, *product;
// Match USB by VID and PID
HIDInterfaceMatcher matcher = { vendor_id, product_id, NULL, NULL, 0 };
// Enable debugging
// hid_set_debug(HID_DEBUG_ALL);
// hid_set_debug_stream(stderr);
// hid_set_usb_debug(0);
// Initialize HID
ret = hid_init();
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_init failed with return code %d\n", ret);
return 1;
} else {
fprintf(stderr, "*** hid_init success! ***\n");
}
hid = hid_new_HIDInterface();
if (hid == 0) {
fprintf(stderr, "hid_new_HIDInterface() failed, out of memory?\n");
return 1;
} else {
fprintf(stderr, "*** hid_new_HIDInterface success! ***\n");
}
//TODO: Use hotplug or give permission to USB without sudo
/* How to detach a device from the kernel HID driver:
*
* The hid.o or usbhid.ko kernel modules claim a HID device on insertion,
* usually. To be able to use it with libhid, you need to blacklist the
* device (which requires a kernel recompilation), or simply tell libhid to
* detach it for you. hid_open just opens the device, hid_force_open will
* try n times to detach the device before failing.
*
* To open the HID, you need permission to the file in the /proc usbfs
* (which must be mounted -- most distros do that by default):
* mount -t usbfs none /proc/bus/usb
* You can use hotplug to automatically give permissions to the device on
* connection. Please see
* http://cvs.ailab.ch/cgi-bin/viewcvs.cgi/external/libphidgets/hotplug/
* for an example. Try NOT to work as root!
*/
// Detach kernel
ret = hid_force_open(hid, iface_num, &matcher, 25);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_force_open failed with return code %d\n", ret);
return 1;
} else {
fprintf(stderr, "*** hid_forcE_open success! ***\n");
}
ret = hid_write_identification(stdout, hid);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_write_identification failed with return code %d\n", ret);
return 1;
} else {
fprintf(stderr, "*** hid_write_identification success! ***\n");
}
ret = hid_dump_tree(stdout, hid);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_dump_tree failed with return code %d\n", ret);
return 1;
} else {
fprintf(stderr, "*** hid_dump_tree success! ***\n");
}
RFIDCommunication(ret, &hid);
printf("\n\n/* * * * * * * * END COMMUNICATION WITH RFID DEVICE * * * * * * * */\n\n");
ret = hid_close(hid);
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_close failed with return code %d\n", ret);
return 1;
} else {
fprintf(stderr, "*** hid_close successful! ***\n");
}
hid_delete_HIDInterface(&hid);
ret = hid_cleanup();
if (ret != HID_RET_SUCCESS) {
fprintf(stderr, "hid_cleanup failed with return code %d\n", ret);
return 1;
} else {
fprintf(stderr, "*** hid_cleanup successful! ***\n");
}
return 0;
}