RflySimSDK v3.08
RflySimSDK说明文档
载入中...
搜索中...
未找到
vrpn_HumanInterface.h
1// vrpn_HumanInterface.h: Generic USB HID driver I/O interface.
2// This implementation uses the cross-platform HIDAPI library
3// from http://www.signal11.us/oss/hidapi/ to handle the cross-
4// platform HID device interface. The older version had a different
5// implementation for each platform; it has been discontinued as
6// of version 7.29.
7
8/* For looking at the types of inforamtion that a device can send, we can use
9 the following (from a post at microchip.com/forums)
10
11 mcuee@Ubuntu804:~$ lsusb
12 Bus 002 Device 010: ID 04f2:0760 Chicony Electronics Co., Ltd
13 Bus 002 Device 007: ID ffff:0005
14 Bus 002 Device 005: ID 046d:c054 Logitech, Inc.
15 Bus 002 Device 004: ID 14c0:0008
16 Bus 002 Device 003: ID 1947:0033
17 Bus 002 Device 002: ID 058f:9360 Alcor Micro Corp. 8-in-1 Media Card Reader
18 Bus 002 Device 001: ID 0000:0000
19 Bus 001 Device 001: ID 0000:0000
20 mcuee@Ubuntu804:~$ sudo libhid-detach-device 04f2:0760
21 Trying to detach HID with IDs 04f2:0760... done.
22 mcuee@Ubuntu804:~$ sudo lsusb -vvv | more
23
24 Bus 002 Device 010: ID 04f2:0760 Chicony Electronics Co., Ltd
25 Device Descriptor:
26 bLength 18
27 bDescriptorType 1
28*/
29
30#ifndef VRPN_HUMANINTERFACE_H
31#define VRPN_HUMANINTERFACE_H
32
33#include <stddef.h> // for size_t
34#include <wchar.h> // for wcscmp
35
36#include "vrpn_Configure.h" // for VRPN_API, VRPN_USE_HID, etc
37#include "vrpn_Types.h" // for vrpn_uint16, vrpn_uint8
38#include "vrpn_OwningPtr.h"
39
41 vrpn_uint16 vendor; // USB Vendor ID
42 vrpn_uint16 product; // USB Product ID
43 wchar_t *serial_number; // USB device serial number
44 wchar_t *manufacturer_string;
45 wchar_t *product_string;
46 int interface_number;
47 const char *path;
48};
49
50// General interface for device enumeration:
51// vrpn_HidInterface will connect to the first device your class accepts.
52// The reset() method will be called before starting a new enumueration, in
53// case you want to connect to the second or third device found that matches
54// some criterion. There are some example HID acceptors at the end of
55// this file.
56class VRPN_API vrpn_HidAcceptor {
57public:
58 virtual ~vrpn_HidAcceptor() {}
59 virtual bool accept(const vrpn_HIDDEVINFO &device) = 0;
60 virtual void reset() {}
61};
62
63#if defined(VRPN_USE_HID)
64
65// Forward declarations for hid_device
66struct hid_device_;
67typedef struct hid_device_ hid_device;
68
69// Main VRPN API for HID devices
70class VRPN_API vrpn_HidInterface {
71public:
72 /// Constructor
73 /// If we already have a HID device from some other source, it can be passed
74 /// and we'll take ownership: still need the acceptor for reconnect, we just
75 /// won't do it right away.
77 /// Determines which device we want
78 vrpn_HidAcceptor *acceptor,
79 /// Default vendor is "any"
80 vrpn_uint16 vendor = 0,
81 /// Default product is "any"
82 vrpn_uint16 product = 0,
83 /// Optional underlying HID device to manage and take ownership of
84 hid_device *device = NULL);
85
86 /// Simplified constructor that just takes an acceptor and an underlying HID
87 /// device (both non-optional).
88 ///
89 /// Designed for passing in a device (May look at you funny if you pass a
90 /// NULL device, but will work just as if you had called the other
91 /// constructor with a null device) but handles NULL devices just fine.
93 /// Determines which device we want
94 vrpn_HidAcceptor *acceptor,
95 /// Underlying HID device to manage and take ownership of
96 hid_device *device);
97
98 /// Constructor
99 /// If we already know the path to the device we want, we can pass it in and
100 /// open it directly: still need the acceptor for reconnect enumeration, we
101 /// just won't do it right away.
103 /// Platform-specific device path, suitable to be passed to HIDAPI's
104 /// hid_open_path
105 const char *device_path,
106 /// Determines which device we want
107 vrpn_HidAcceptor *acceptor,
108 /// Default vendor is "any"
109 vrpn_uint16 vendor = 0,
110 /// Default product is "any"
111 vrpn_uint16 product = 0);
112
113 virtual ~vrpn_HidInterface();
114
115 /// Returns true iff the last device I/O succeeded
116 virtual bool connected() const;
117
118 /// Polls the device buffers and causes on_data_received callbacks if
119 /// appropriate
120 /// You NEED to call this frequently to ensure the OS doesn't drop data
121 virtual void update();
122
123 /// Tries to reconnect to an acceptable device.
124 /// Call this if you suspect a hotplug event has occurred.
125 virtual bool reconnect();
126
127 /// Returns USB vendor ID of connected device
128 /// May not contain valid if an already-open device was provided to the
129 /// constructor.
130 vrpn_uint16 vendor() const;
131
132 /// Returns USB product ID of connected device
133 /// May not contain valid if an already-open device was provided to the
134 /// constructor.
135 vrpn_uint16 product() const;
136
137 /// Returns the USB interface number of connected device
138 /// May not contain valid information on all platforms or if an already-open
139 /// device was provided to the constructor.
140 int interface_number() const;
141
142protected:
143 /** @brief Derived class reimplements this callback. It is called whenever
144 a read returns some data.
145
146 WARNING! The data returned by this function differs when the device
147 sends multiple report types and when it only has one. When it
148 can have more than one, the report type is sent as the first byte.
149 When it only has one, the report type is NOT included. This is
150 the behavior of the HIDAPI library we are using. It is surprising
151 to me, but that's how it behaves.
152 */
153 virtual void on_data_received(size_t bytes, vrpn_uint8 *buffer) = 0;
154
155 /// Call this to send data to the device
156 void send_data(size_t bytes, const vrpn_uint8 *buffer);
157
158 /// Call this to send a feature report to the device - first byte must be
159 /// Report ID (or 0x0 for devices without numbered reports)
160 void send_feature_report(size_t bytes, const vrpn_uint8 *buffer);
161
162 /// Call this to get a feature report from the device - first byte must be
163 /// Report ID (or 0x0 for devices without numbered reports)
164 /// @return Number of bytes received, or -1 on error
165 int get_feature_report(size_t bytes, vrpn_uint8 *buffer);
166
167 /** @brief This is the HidAcceptor we use when reconnecting.
168
169 We do not take ownership of the pointer; it is the user's
170 responsibility. Using a stack-allocated acceptor is a really good way to
171 get a segfault when calling reconnect()--there won't be an acceptor there
172 any longer!
173 Thus, always use "new" to make your acceptors.
174 */
176
177 bool m_working;
178 vrpn_uint16 m_vendor;
179 vrpn_uint16 m_product;
180 int m_interface;
181
182 // These are passed in the constructor and kept for use by the
183 // reconnect() method. Strictly speaking, they are redundant
184 // because you can put an acceptor that only matches the given
185 // vendor and product ID. However, at least one HID device on at
186 // least one server times out when repeatedly polled for its
187 // info during hid_enumerate() if we don't check for the correct
188 // vendor and product ID and ignore it, so we made this an optional
189 // setting in the constructor.
190 vrpn_uint16 m_vendor_sought; //!< What vendor we want
191 vrpn_uint16 m_product_sought; //!< What product we want
192
193private:
194 // finishing setup of a device, either passed in or recently opened.
195 bool finish_setup();
196 // Report an error message, which will be augmented with a HIDAPI error
197 // message if one is available and desired
198 void print_error(const char *function, const char *msg,
199 bool askHIDAPI = true) const;
200 // Performs just the HIDAPI portion of print_error.
201 void print_hidapi_error(const char *function) const;
202 hid_device *m_device; ///< The HID device to use.
203};
204
205#endif // VRPN_USE_HID
206
207// Some sample acceptors
208
209/// Always accepts the first device passed. Pointless by itself except for
210/// testing.
212public:
213 bool accept(const vrpn_HIDDEVINFO &) { return true; }
214};
215
216/// Accepts any device with the given vendor and product IDs.
218public:
219 vrpn_HidProductAcceptor(vrpn_uint16 vendorId, vrpn_uint16 productId)
220 : product(productId)
221 , vendor(vendorId)
222 {
223 }
224 bool accept(const vrpn_HIDDEVINFO &device)
225 {
226 return (device.vendor == vendor) && (device.product == product);
227 }
228
229private:
230 vrpn_uint16 product, vendor;
231};
232
233/// Accepts any device with a particular serial number.
235public:
236 vrpn_HidSerialNumberAcceptor(const wchar_t *serial)
237 : devNum(serial)
238 {
239 }
240 bool accept(const vrpn_HIDDEVINFO &device)
241 {
242 return !wcscmp(devNum, device.serial_number);
243 }
244
245private:
246 const wchar_t *devNum;
247};
248
249/// Accepts any device with a particular interface number. Best in conjunction
250/// with vrpn_HidBooleanAndAcceptor.
252public:
254 : _iface(iface)
255 {
256 }
257 bool accept(const vrpn_HIDDEVINFO &device)
258 {
259 return _iface == device.interface_number;
260 }
261
262private:
263 const int _iface;
264};
265
266/** @brief Accepts the Nth device matching a given acceptor.
267
268 This demonstrates the composition of acceptors, allowing the user/programmer
269 to create a more specific Hid object without needing to duplicate code all
270 over the place.
271*/
273public:
274 vrpn_HidNthMatchAcceptor(size_t index, vrpn_HidAcceptor *acceptor)
275 : target(index)
276 , found(0)
277 , delegate(acceptor)
278 {
279 }
280
281 virtual ~vrpn_HidNthMatchAcceptor() {}
282
283 bool accept(const vrpn_HIDDEVINFO &device)
284 {
285 return delegate->accept(device) && (found++ == target);
286 }
287 void reset()
288 {
289 found = 0;
290 delegate->reset();
291 }
292
293private:
294 size_t target, found;
296};
297
298/// Accepts only devices meeting two criteria. NOT SHORT-CIRCUIT.
299/// Another demonstration of acceptor composition.
301public:
303 : first(p)
304 , second(q)
305 {
306 }
307
308 virtual ~vrpn_HidBooleanAndAcceptor() {}
309
310 bool accept(const vrpn_HIDDEVINFO &device)
311 {
312 bool p = first->accept(device);
313 bool q = second->accept(device);
314 return p && q;
315 }
316
317 void reset()
318 {
319 first->reset();
320 second->reset();
321 }
322
323private:
326};
327
328/// Accepts devices meeting at least one of two criteria. NOT SHORT-CIRCUIT.
329/// Another demonstration of acceptor composition.
331public:
333 : first(p)
334 , second(q)
335 {
336 }
337
338 virtual ~vrpn_HidBooleanOrAcceptor() {}
339
340 bool accept(const vrpn_HIDDEVINFO &device)
341 {
342 bool p = first->accept(device);
343 bool q = second->accept(device);
344 return p || q;
345 }
346
347 void reset()
348 {
349 first->reset();
350 second->reset();
351 }
352
353private:
356};
357
358/// @todo Operators for these acceptors (really predicates) ?
359
360#endif // VRPN_HUMANINTERFACE_H
定义 vrpn_OwningPtr.h:74
定义 vrpn_HumanInterface.h:56
定义 vrpn_HumanInterface.h:211
定义 vrpn_HumanInterface.h:300
定义 vrpn_HumanInterface.h:330
定义 vrpn_HumanInterface.h:251
定义 vrpn_HumanInterface.h:70
int get_feature_report(size_t bytes, vrpn_uint8 *buffer)
vrpn_HidAcceptor * m_acceptor
This is the HidAcceptor we use when reconnecting.
定义 vrpn_HumanInterface.h:175
vrpn_uint16 product() const
virtual void on_data_received(size_t bytes, vrpn_uint8 *buffer)=0
Derived class reimplements this callback. It is called whenever a read returns some data.
vrpn_HidInterface(vrpn_HidAcceptor *acceptor, vrpn_uint16 vendor=0, vrpn_uint16 product=0, hid_device *device=NULL)
vrpn_HidInterface(const char *device_path, vrpn_HidAcceptor *acceptor, vrpn_uint16 vendor=0, vrpn_uint16 product=0)
int interface_number() const
virtual bool connected() const
Returns true iff the last device I/O succeeded
void send_data(size_t bytes, const vrpn_uint8 *buffer)
Call this to send data to the device
vrpn_uint16 vendor() const
vrpn_HidInterface(vrpn_HidAcceptor *acceptor, hid_device *device)
virtual void update()
virtual bool reconnect()
vrpn_uint16 m_vendor_sought
What vendor we want
定义 vrpn_HumanInterface.h:190
void send_feature_report(size_t bytes, const vrpn_uint8 *buffer)
vrpn_uint16 m_product_sought
What product we want
定义 vrpn_HumanInterface.h:191
Accepts the Nth device matching a given acceptor.
定义 vrpn_HumanInterface.h:272
Accepts any device with the given vendor and product IDs.
定义 vrpn_HumanInterface.h:217
Accepts any device with a particular serial number.
定义 vrpn_HumanInterface.h:234
定义 vrpn_HumanInterface.h:40