Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 205 lines (176 sloc) 6.762 kb
6d6cd43 This was always just a copy of vrpn.cfg. No sense having two copies of ...
taylorr authored
1 #include "vrpn_HumanInterface.h"
2
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
3 #if defined(VRPN_USE_HID)
6d6cd43 This was always just a copy of vrpn.cfg. No sense having two copies of ...
taylorr authored
4
5 // Accessor for USB vendor ID of connected device
6 vrpn_uint16 vrpn_HidInterface::vendor() const {
7 return _vendor;
8 }
9
10 // Accessor for USB product ID of connected device
11 vrpn_uint16 vrpn_HidInterface::product() const {
12 return _product;
13 }
14
a4de9e3 Ryan Pavlik HidInterface keeps track of interface number now too
authored
15 // Accessor for USB interface number of connected device
16 int vrpn_HidInterface::interface_number() const {
17 return _interface;
18 }
19
6d6cd43 This was always just a copy of vrpn.cfg. No sense having two copies of ...
taylorr authored
20 // Returns true iff everything was working last time we checked
21 bool vrpn_HidInterface::connected() const {
22 return _working;
23 }
24
25
8ac3ee8 2009-09-24 Russell M. Taylor II <taylorr@cs.unc.edu>
taylorr authored
26 vrpn_HidInterface::vrpn_HidInterface(vrpn_HidAcceptor *acceptor)
27 : _acceptor(acceptor)
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
28 , _device(NULL)
8ac3ee8 2009-09-24 Russell M. Taylor II <taylorr@cs.unc.edu>
taylorr authored
29 , _working(false)
30 , _vendor(0)
31 , _product(0)
a4de9e3 Ryan Pavlik HidInterface keeps track of interface number now too
authored
32 , _interface(0)
8ac3ee8 2009-09-24 Russell M. Taylor II <taylorr@cs.unc.edu>
taylorr authored
33 {
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
34 if (_acceptor == NULL) {
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
35 fprintf(stderr,"vrpn_HidInterface::vrpn_HidInterface(): NULL acceptor\n");
36 return;
37 }
38
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
39 // Reset the acceptor and then attempt to connect to a device.
40 _acceptor->reset();
41 reconnect();
42 }
43
44 vrpn_HidInterface::~vrpn_HidInterface()
45 {
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
46 if (_device) {
47 hid_close(_device);
48 _device = NULL;
49 }
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
50 }
51
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
52 // Reconnects the device I/O for the first acceptable device
53 // Called automatically by constructor, but userland code can
54 // use it to reacquire a hotplugged device.
55 void vrpn_HidInterface::reconnect() {
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
56
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
57 // Enumerate all devices and pass each one to the acceptor to see if it is the
58 // one that we want.
59 struct hid_device_info *devs = hid_enumerate(0, 0);
60 struct hid_device_info *loop = devs;
61 bool found = false;
62 const wchar_t *serial;
63 while ((loop != NULL) && !found) {
64 vrpn_HIDDEVINFO device_info;
65 device_info.vendor = loop->vendor_id;
66 device_info.product = loop->product_id;
67 device_info.serial_number = loop->serial_number;
68 device_info.manufacturer_string = loop->manufacturer_string;
69 device_info.product_string = loop->product_string;
d37556a Ryan Pavlik Allow acceptors to investigate interface number, for composite devices
authored
70 device_info.interface_number = loop->interface_number;
e3339bd Russell Taylor Moved the list-deletion code from two places to one place. Added a comm...
russell-taylor authored
71 //printf("XXX Found vendor %x, product %x\n", (unsigned)(loop->vendor_id), (unsigned)(loop->product_id));
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
72
73 if (_acceptor->accept(device_info)) {
74 _vendor = loop->vendor_id;
75 _product = loop->product_id;
a4de9e3 Ryan Pavlik HidInterface keeps track of interface number now too
authored
76 _interface = loop->interface_number;
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
77 serial = loop->serial_number;
78 found = true;
79 }
80 loop = loop->next;
81 }
82 if (!found) {
83 fprintf(stderr,"vrpn_HidInterface::reconnect(): Device not found\n");
84 return;
85 }
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
86
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
87 // Initialize the HID interface and open the device.
88 _device = hid_open(_vendor, _product, const_cast<wchar_t *>(serial));
89 if (_device == NULL) {
90 fprintf(stderr,"vrpn_HidInterface::reconnect(): Could not open device\n");
91 #ifdef linux
92 fprintf(stderr," (Did you remember to run as root?)\n");
93 #endif
94 return;
95 }
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
96
b49055a Removed race condition on serial number being deleted before being used.
Russell Taylor authored
97 // We cannot do this before the call to open because the serial number
98 // is a pointer to a string down in there, which forms a race condition.
99 // This will be a memory leak if the device fails to open.
100 if (devs != NULL) {
101 hid_free_enumeration(devs);
102 devs = NULL;
103 }
104
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
105 // Set the device to non-blocking mode.
106 if (hid_set_nonblocking(_device, 1) != 0) {
107 fprintf(stderr,"vrpn_HidInterface::reconnect(): Could not set device to nonblocking\n");
108 return;
109 }
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
110
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
111 _working = true;
112 }
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
113
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
114 // Check for incoming characters. If we get some, pass them on to the handler code.
115 // This is based on the source code for the hid_interrupt_read() function; it goes
457bc1c Has an implementation of libhid/libusb for USB HID devices on Linux. Th...
Russell Taylor authored
116 // down to the libusb interface directly to get any available characters. Because
117 // we're trying to support a generic device, we can't say in advance how large any
dbffc1a Russell Taylor Removed the timeout and report-length parameters from the update() call ...
russell-taylor authored
118 // particular transfer should be. So we try to one character at a time until we
119 // don't have any more to read. This update() routine must be called
457bc1c Has an implementation of libhid/libusb for USB HID devices on Linux. Th...
Russell Taylor authored
120 // frequently to make sure we don't get partial results, which would mean sending
121 // truncated reports to the devices derived from us.
122
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
123 void vrpn_HidInterface::update()
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
124 {
125 if (!_working) {
4662495 Removes messages that spam the console.
Russell Taylor authored
126 //fprintf(stderr,"vrpn_HidInterface::update(): Interface not currently working\n");
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
127 return;
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
128 }
129
dbffc1a Russell Taylor Removed the timeout and report-length parameters from the update() call ...
russell-taylor authored
130 // Maximum packet size for USB is 512 characters.
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
131 vrpn_uint8 inbuf[512];
457bc1c Has an implementation of libhid/libusb for USB HID devices on Linux. Th...
Russell Taylor authored
132 if (inbuf == NULL) {
133 fprintf(stderr,"vrpn_HidInterface::update(): Out of memory\n");
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
134 return;
135 }
136
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
137 int ret = hid_read(_device, inbuf, sizeof(inbuf));
138 if (ret < 0) {
139 fprintf(stderr,"vrpn_HidInterface::update(): Read error\n");
140 return;
141 }
457bc1c Has an implementation of libhid/libusb for USB HID devices on Linux. Th...
Russell Taylor authored
142
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
143 // Handle any data we got. This can include fewer bytes than we
144 // asked for.
145 if (ret > 0) {
dbffc1a Russell Taylor Removed the timeout and report-length parameters from the update() call ...
russell-taylor authored
146 vrpn_uint8 *data = static_cast<vrpn_uint8 *>(static_cast<void*>(inbuf));
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
147 on_data_received(ret, data);
dbffc1a Russell Taylor Removed the timeout and report-length parameters from the update() call ...
russell-taylor authored
148 }
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
149 }
150
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
151 // This is based on sample code from UMinn Duluth at
00e326d Ryan Pavlik clean up link to sample code inspiring send_data
authored
152 // http://www.d.umn.edu/~cprince/PubRes/Hardware/LinuxUSB/PICDEM/tutorial1.c
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
153 // It has not yet been tested.
154
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
155 void vrpn_HidInterface::send_data(size_t bytes, const vrpn_uint8 *buffer)
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
156 {
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
157 if (!_working) {
158 fprintf(stderr,"vrpn_HidInterface::send_data(): Interface not currently working\n");
159 return;
160 }
161 int ret;
162 if ( (ret = hid_write(_device, const_cast<vrpn_uint8 *>(buffer), bytes)) != bytes) {
a7e2e19 Complete but not-yet-fully-working implementation of libhid interface to...
Russell Taylor authored
163 fprintf(stderr,"vrpn_HidInterface::send_data(): hid_interrupt_write() failed with code %d\n", ret);
164 }
61f1595 Initial steps towards implementing a USB HID interface under Linux. Thi...
Russell Taylor authored
165 }
166
c662f11 Ryan Pavlik add method to vrpn_HidInterface to send a feature report
authored
167 void vrpn_HidInterface::send_feature_report(size_t bytes, const vrpn_uint8 *buffer) {
168 if (!_working) {
169 fprintf(stderr,"vrpn_HidInterface::send_feature_report(): Interface not currently working\n");
170 return;
171 }
99ee7c6 Ryan Pavlik remove some debug prints in HumanInterface
authored
172
c662f11 Ryan Pavlik add method to vrpn_HidInterface to send a feature report
authored
173 int ret = hid_send_feature_report(_device, buffer, bytes);
9523635 Ryan Pavlik fix comparison bug in new HumanInterface methods
authored
174 if (ret == -1) {
c662f11 Ryan Pavlik add method to vrpn_HidInterface to send a feature report
authored
175 fprintf(stderr, "vrpn_HidInterface::send_feature_report(): failed to send feature report\n");
aba6241 Ryan Pavlik Add use of the hidapi error messages to the HID class.
authored
176 const wchar_t * errmsg = hid_error(_device);
177 if (errmsg) {
178 fprintf(stderr, "vrpn_HidInterface::send_feature_report(): error message: %ls\n", errmsg);
179 }
c662f11 Ryan Pavlik add method to vrpn_HidInterface to send a feature report
authored
180 } else {
99ee7c6 Ryan Pavlik remove some debug prints in HumanInterface
authored
181 //fprintf(stderr, "vrpn_HidInterface::send_feature_report(): sent feature report, %d bytes\n", static_cast<int>(bytes));
c662f11 Ryan Pavlik add method to vrpn_HidInterface to send a feature report
authored
182 }
183 }
184
92de535 Ryan Pavlik add method for getting feature report
authored
185 int vrpn_HidInterface::get_feature_report(size_t bytes, vrpn_uint8 *buffer) {
186 if (!_working) {
187 fprintf(stderr,"vrpn_HidInterface::get_feature_report(): Interface not currently working\n");
188 return -1;
189 }
99ee7c6 Ryan Pavlik remove some debug prints in HumanInterface
authored
190
92de535 Ryan Pavlik add method for getting feature report
authored
191 int ret = hid_get_feature_report(_device, buffer, bytes);
9523635 Ryan Pavlik fix comparison bug in new HumanInterface methods
authored
192 if (ret == -1) {
92de535 Ryan Pavlik add method for getting feature report
authored
193 fprintf(stderr, "vrpn_HidInterface::get_feature_report(): failed to get feature report\n");
aba6241 Ryan Pavlik Add use of the hidapi error messages to the HID class.
authored
194 const wchar_t * errmsg = hid_error(_device);
195 if (errmsg) {
196 fprintf(stderr, "vrpn_HidInterface::get_feature_report(): error message: %ls\n", errmsg);
197 }
92de535 Ryan Pavlik add method for getting feature report
authored
198 } else {
99ee7c6 Ryan Pavlik remove some debug prints in HumanInterface
authored
199 //fprintf(stderr, "vrpn_HidInterface::get_feature_report(): got feature report, %d bytes\n", static_cast<int>(bytes));
92de535 Ryan Pavlik add method for getting feature report
authored
200 }
201 return ret;
202 }
203
f918f6b Russell Taylor Major changes to VRPN HID device code. Replaced the custom per-architec...
russell-taylor authored
204 #endif // any interface
Something went wrong with that request. Please try again.