-
Notifications
You must be signed in to change notification settings - Fork 0
/
wspusb.c
150 lines (122 loc) · 3.67 KB
/
wspusb.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
//
// Weather Station Poller
//
// Copyright (C) 2010 Joakim Söderberg
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <stdio.h>
#include <assert.h>
#include "wsp.h"
#include "wspusb.h"
//
// Finds the device based on vendor and product id.
//
struct usb_device *find_device(int vendor, int product)
{
struct usb_bus *bus;
struct usb_device *dev;
for (bus = usb_get_busses(); bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
if (dev->descriptor.idVendor == vendor
&& dev->descriptor.idProduct == product)
{
return dev;
}
}
}
return NULL;
}
//
// Closes the connection to the USB device.
//
void close_device(struct usb_dev_handle *h)
{
int ret = usb_release_interface(h, 0);
if (ret != 0)
fprintf(stderr, "Could not release interface: %d\n", ret);
ret = usb_close(h);
if (ret != 0)
fprintf(stderr, "Error closing interface: %d\n", ret);
}
//
// Opens the USB device.
//
struct usb_dev_handle *open_device()
{
int ret;
struct usb_dev_handle *h;
struct usb_device *dev;
char buf[1024];
usb_init();
usb_find_busses();
usb_find_devices();
dev = find_device(program_settings.vendor_id, program_settings.product_id);
if (!dev)
{
fprintf(stderr, "No device with vendor id: 0x%x (%d) and product id: %x (%d) was found\n",
program_settings.vendor_id, program_settings.vendor_id,
program_settings.product_id, program_settings.product_id);
exit(1);
}
h = usb_open(dev);
assert(h);
#ifdef LIBUSB_HAS_GET_DRIVER_NP
ret = usb_get_driver_np(h, 0, buf, sizeof(buf));
if (ret == 0)
{
if ((ret = usb_detach_kernel_driver_np(h, 0)) != 0)
{
fprintf(stderr, "Could not open usb device. Failed o detached from driver \"%s\": %d\n", buf, ret);
exit(1);
}
}
#endif // LIBUSB_HAS_GET_DRIVER_NP
// TODO: Add support for using HIDAPI instead on OSX. http://www.libusb.org/ticket/89
ret = usb_claim_interface(h, 0);
if (ret != 0)
{
fprintf(stderr, "Could not open usb device, errorcode: %d\n", ret);
exit(1);
}
ret = usb_set_altinterface(h, 0);
if (!h || ret != 0)
{
fprintf(stderr, "Failed to open USB device, errorcode: %d\n", ret);
exit(1);
}
return h;
}
//
// Inits the USB descriptors.
//
void init_device_descriptors(struct usb_dev_handle *h)
{
char buf[1024];
int ret = 0;
ret = usb_get_descriptor(h, USB_DT_DEVICE, 0, buf, sizeof(buf));
ret = usb_get_descriptor(h, USB_DT_CONFIG, 0, buf, sizeof(buf));
ret = usb_release_interface(h, 0);
if (ret != 0)
fprintf(stderr, "Failed to release interface before set_configuration: %d\n", ret);
ret = usb_set_configuration(h, 1);
ret = usb_claim_interface(h, 0);
if (ret != 0)
fprintf(stderr, "Claim after set_configuration failed with error: %d\n", ret);
ret = usb_set_altinterface(h, 0);
ret = usb_control_msg(h, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 0xa, 0, 0, NULL, 0, USB_TIMEOUT);
ret = usb_get_descriptor(h, USB_DT_REPORT, 0, buf, sizeof(buf));
}