usb 1.7.2-prebuild

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/.github/workflows/prebuild.yml +62 -0
  2. package/.gitmodules +3 -0
  3. package/LICENSE +7 -0
  4. package/Readme.md +339 -0
  5. package/binding.gyp +90 -0
  6. package/libusb/.gitattributes +11 -0
  7. package/libusb/.private/README.txt +5 -0
  8. package/libusb/.private/bd.cmd +89 -0
  9. package/libusb/.private/bm.sh +54 -0
  10. package/libusb/.private/bwince.cmd +57 -0
  11. package/libusb/.private/post-rewrite.sh +28 -0
  12. package/libusb/.private/pre-commit.sh +42 -0
  13. package/libusb/.private/wbs.txt +61 -0
  14. package/libusb/.private/wbs_wince.txt +42 -0
  15. package/libusb/AUTHORS +78 -0
  16. package/libusb/COPYING +504 -0
  17. package/libusb/ChangeLog +211 -0
  18. package/libusb/INSTALL +234 -0
  19. package/libusb/INSTALL_WIN.txt +73 -0
  20. package/libusb/Makefile.am +28 -0
  21. package/libusb/NEWS +2 -0
  22. package/libusb/PORTING +94 -0
  23. package/libusb/README +28 -0
  24. package/libusb/README.git +41 -0
  25. package/libusb/TODO +2 -0
  26. package/libusb/Xcode/common.xcconfig +49 -0
  27. package/libusb/Xcode/debug.xcconfig +29 -0
  28. package/libusb/Xcode/libusb.xcconfig +21 -0
  29. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +1 -0
  30. package/libusb/Xcode/libusb_debug.xcconfig +21 -0
  31. package/libusb/Xcode/libusb_release.xcconfig +21 -0
  32. package/libusb/Xcode/release.xcconfig +30 -0
  33. package/libusb/android/README +114 -0
  34. package/libusb/android/jni/Android.mk +23 -0
  35. package/libusb/android/jni/Application.mk +24 -0
  36. package/libusb/android/jni/examples.mk +134 -0
  37. package/libusb/android/jni/libusb.mk +54 -0
  38. package/libusb/android/jni/tests.mk +56 -0
  39. package/libusb/autogen.sh +8 -0
  40. package/libusb/bootstrap.sh +19 -0
  41. package/libusb/configure.ac +304 -0
  42. package/libusb/doc/Makefile.am +9 -0
  43. package/libusb/doc/doxygen.cfg.in +1288 -0
  44. package/libusb/doc/libusb.png +0 -0
  45. package/libusb/examples/Makefile.am +19 -0
  46. package/libusb/examples/dpfp.c +506 -0
  47. package/libusb/examples/dpfp_threaded.c +544 -0
  48. package/libusb/examples/ezusb.c +831 -0
  49. package/libusb/examples/ezusb.h +120 -0
  50. package/libusb/examples/fxload.c +287 -0
  51. package/libusb/examples/getopt/getopt.c +1060 -0
  52. package/libusb/examples/getopt/getopt.h +180 -0
  53. package/libusb/examples/getopt/getopt1.c +188 -0
  54. package/libusb/examples/hotplugtest.c +104 -0
  55. package/libusb/examples/listdevs.c +71 -0
  56. package/libusb/examples/sam3u_benchmark.c +193 -0
  57. package/libusb/examples/xusb.c +1129 -0
  58. package/libusb/libusb/Makefile.am +75 -0
  59. package/libusb/libusb/core.c +2342 -0
  60. package/libusb/libusb/descriptor.c +1199 -0
  61. package/libusb/libusb/hotplug.c +327 -0
  62. package/libusb/libusb/hotplug.h +82 -0
  63. package/libusb/libusb/io.c +2631 -0
  64. package/libusb/libusb/libusb-1.0.def +166 -0
  65. package/libusb/libusb/libusb-1.0.rc +61 -0
  66. package/libusb/libusb/libusb.h +1998 -0
  67. package/libusb/libusb/libusbi.h +1040 -0
  68. package/libusb/libusb/os/darwin_usb.c +2009 -0
  69. package/libusb/libusb/os/darwin_usb.h +162 -0
  70. package/libusb/libusb/os/linux_netlink.c +369 -0
  71. package/libusb/libusb/os/linux_udev.c +307 -0
  72. package/libusb/libusb/os/linux_usbfs.c +2695 -0
  73. package/libusb/libusb/os/linux_usbfs.h +192 -0
  74. package/libusb/libusb/os/netbsd_usb.c +738 -0
  75. package/libusb/libusb/os/openbsd_usb.c +832 -0
  76. package/libusb/libusb/os/poll_posix.c +51 -0
  77. package/libusb/libusb/os/poll_posix.h +11 -0
  78. package/libusb/libusb/os/poll_windows.c +796 -0
  79. package/libusb/libusb/os/poll_windows.h +131 -0
  80. package/libusb/libusb/os/threads_posix.c +82 -0
  81. package/libusb/libusb/os/threads_posix.h +50 -0
  82. package/libusb/libusb/os/threads_windows.c +212 -0
  83. package/libusb/libusb/os/threads_windows.h +87 -0
  84. package/libusb/libusb/os/wince_usb.c +1032 -0
  85. package/libusb/libusb/os/wince_usb.h +131 -0
  86. package/libusb/libusb/os/windows_common.h +108 -0
  87. package/libusb/libusb/os/windows_usb.c +5347 -0
  88. package/libusb/libusb/os/windows_usb.h +971 -0
  89. package/libusb/libusb/strerror.c +199 -0
  90. package/libusb/libusb/sync.c +307 -0
  91. package/libusb/libusb/version.h +18 -0
  92. package/libusb/libusb/version_nano.h +1 -0
  93. package/libusb/libusb-1.0.pc.in +11 -0
  94. package/libusb/msvc/config.h +50 -0
  95. package/libusb/msvc/ddk_build.cmd +175 -0
  96. package/libusb/msvc/errno.h +102 -0
  97. package/libusb/msvc/fxload_2010.vcxproj +170 -0
  98. package/libusb/msvc/fxload_2010.vcxproj.filters +25 -0
  99. package/libusb/msvc/fxload_2012.vcxproj +174 -0
  100. package/libusb/msvc/fxload_2012.vcxproj.filters +25 -0
  101. package/libusb/msvc/fxload_2013.vcxproj +174 -0
  102. package/libusb/msvc/fxload_sources +23 -0
  103. package/libusb/msvc/getopt_2005.vcproj +288 -0
  104. package/libusb/msvc/getopt_2010.vcxproj +131 -0
  105. package/libusb/msvc/getopt_2010.vcxproj.filters +26 -0
  106. package/libusb/msvc/getopt_2012.vcxproj +136 -0
  107. package/libusb/msvc/getopt_2012.vcxproj.filters +26 -0
  108. package/libusb/msvc/getopt_2013.vcxproj +136 -0
  109. package/libusb/msvc/getopt_sources +20 -0
  110. package/libusb/msvc/hotplugtest_2010.vcxproj +163 -0
  111. package/libusb/msvc/hotplugtest_2010.vcxproj.filters +14 -0
  112. package/libusb/msvc/hotplugtest_2012.vcxproj +167 -0
  113. package/libusb/msvc/hotplugtest_2012.vcxproj.filters +14 -0
  114. package/libusb/msvc/hotplugtest_2013.vcxproj +167 -0
  115. package/libusb/msvc/hotplugtest_sources +20 -0
  116. package/libusb/msvc/inttypes.h +295 -0
  117. package/libusb/msvc/libusb.dsw +71 -0
  118. package/libusb/msvc/libusb_2005.sln +95 -0
  119. package/libusb/msvc/libusb_2010.sln +94 -0
  120. package/libusb/msvc/libusb_2012.sln +94 -0
  121. package/libusb/msvc/libusb_2013.sln +100 -0
  122. package/libusb/msvc/libusb_2015.sln +100 -0
  123. package/libusb/msvc/libusb_dll.dsp +194 -0
  124. package/libusb/msvc/libusb_dll_2005.vcproj +436 -0
  125. package/libusb/msvc/libusb_dll_2010.vcxproj +170 -0
  126. package/libusb/msvc/libusb_dll_2010.vcxproj.filters +81 -0
  127. package/libusb/msvc/libusb_dll_2012.vcxproj +175 -0
  128. package/libusb/msvc/libusb_dll_2012.vcxproj.filters +84 -0
  129. package/libusb/msvc/libusb_dll_2013.vcxproj +175 -0
  130. package/libusb/msvc/libusb_dll_wince.vcproj +1243 -0
  131. package/libusb/msvc/libusb_sources +38 -0
  132. package/libusb/msvc/libusb_static.dsp +174 -0
  133. package/libusb/msvc/libusb_static_2005.vcproj +362 -0
  134. package/libusb/msvc/libusb_static_2010.vcxproj +156 -0
  135. package/libusb/msvc/libusb_static_2010.vcxproj.filters +74 -0
  136. package/libusb/msvc/libusb_static_2012.vcxproj +160 -0
  137. package/libusb/msvc/libusb_static_2012.vcxproj.filters +74 -0
  138. package/libusb/msvc/libusb_static_2013.vcxproj +160 -0
  139. package/libusb/msvc/libusb_static_wince.vcproj +1185 -0
  140. package/libusb/msvc/libusb_wince.sln +246 -0
  141. package/libusb/msvc/listdevs.dsp +103 -0
  142. package/libusb/msvc/listdevs_2005.vcproj +360 -0
  143. package/libusb/msvc/listdevs_2010.vcxproj +165 -0
  144. package/libusb/msvc/listdevs_2010.vcxproj.filters +14 -0
  145. package/libusb/msvc/listdevs_2012.vcxproj +169 -0
  146. package/libusb/msvc/listdevs_2012.vcxproj.filters +14 -0
  147. package/libusb/msvc/listdevs_2013.vcxproj +169 -0
  148. package/libusb/msvc/listdevs_sources +19 -0
  149. package/libusb/msvc/listdevs_wince.vcproj +1120 -0
  150. package/libusb/msvc/missing.c +80 -0
  151. package/libusb/msvc/missing.h +32 -0
  152. package/libusb/msvc/stdint.h +256 -0
  153. package/libusb/msvc/stress_2005.vcproj +390 -0
  154. package/libusb/msvc/stress_2010.vcxproj +167 -0
  155. package/libusb/msvc/stress_2010.vcxproj.filters +25 -0
  156. package/libusb/msvc/stress_2012.vcxproj +171 -0
  157. package/libusb/msvc/stress_2012.vcxproj.filters +25 -0
  158. package/libusb/msvc/stress_2013.vcxproj +171 -0
  159. package/libusb/msvc/stress_wince.vcproj +1128 -0
  160. package/libusb/msvc/xusb.dsp +102 -0
  161. package/libusb/msvc/xusb_2005.vcproj +344 -0
  162. package/libusb/msvc/xusb_2010.vcxproj +163 -0
  163. package/libusb/msvc/xusb_2010.vcxproj.filters +14 -0
  164. package/libusb/msvc/xusb_2012.vcxproj +167 -0
  165. package/libusb/msvc/xusb_2012.vcxproj.filters +14 -0
  166. package/libusb/msvc/xusb_2013.vcxproj +167 -0
  167. package/libusb/msvc/xusb_sources +20 -0
  168. package/libusb/msvc/xusb_wince.vcproj +1120 -0
  169. package/libusb/tests/Makefile.am +6 -0
  170. package/libusb/tests/libusb_testlib.h +107 -0
  171. package/libusb/tests/stress.c +160 -0
  172. package/libusb/tests/testlib.c +281 -0
  173. package/libusb.gypi +136 -0
  174. package/libusb_config/config.h +1 -0
  175. package/package.json +69 -0
  176. package/src/device.cc +412 -0
  177. package/src/helpers.h +64 -0
  178. package/src/node_usb.cc +319 -0
  179. package/src/node_usb.h +120 -0
  180. package/src/transfer.cc +148 -0
  181. package/src/uv_async_queue.h +33 -0
  182. package/test/usb.coffee +191 -0
  183. package/usb.js +524 -0
@@ -0,0 +1,191 @@
1
+ assert = require('assert')
2
+ util = require('util')
3
+ usb = require("../usb.js")
4
+
5
+ if typeof gc is 'function'
6
+ # running with --expose-gc, do a sweep between tests so valgrind blames the right one
7
+ afterEach -> gc()
8
+
9
+ describe 'Module', ->
10
+ it 'should describe basic constants', ->
11
+ assert.notEqual(usb, undefined, "usb must be undefined")
12
+ assert.ok((usb.LIBUSB_CLASS_PER_INTERFACE != undefined), "Constants must be described")
13
+ assert.ok((usb.LIBUSB_ENDPOINT_IN == 128))
14
+
15
+ it 'should handle abuse without crashing', ->
16
+ assert.throws -> new usb.Device()
17
+ assert.throws -> usb.Device()
18
+ assert.throws -> usb.Device.prototype.open.call({})
19
+
20
+ describe 'setDebugLevel', ->
21
+ it 'should throw when passed invalid args', ->
22
+ assert.throws((-> usb.setDebugLevel()), TypeError)
23
+ assert.throws((-> usb.setDebugLevel(-1)), TypeError)
24
+ assert.throws((-> usb.setDebugLevel(5)), TypeError)
25
+
26
+ it 'should succeed with good args', ->
27
+ assert.doesNotThrow(-> usb.setDebugLevel(0))
28
+
29
+ describe 'getDeviceList', ->
30
+ it 'should return at least one device', ->
31
+ l = usb.getDeviceList()
32
+ assert.ok((l.length > 0))
33
+
34
+ describe 'findByIds', ->
35
+ it 'should return an array with length > 0', ->
36
+ dev = usb.findByIds(0x59e3, 0x0a23)
37
+ assert.ok(dev, "Demo device is not attached")
38
+
39
+
40
+ describe 'Device', ->
41
+ device = null
42
+ before ->
43
+ device = usb.findByIds(0x59e3, 0x0a23)
44
+
45
+ it 'should have sane properties', ->
46
+ assert.ok((device.busNumber > 0), "busNumber must be larger than 0")
47
+ assert.ok((device.deviceAddress > 0), "deviceAddress must be larger than 0")
48
+ if process.platform != 'darwin' || process.arch != 'arm64'
49
+ assert.ok((util.isArray(device.portNumbers)), "portNumbers must be an array")
50
+
51
+ it 'should have a deviceDescriptor property', ->
52
+ assert.ok(((deviceDesc = device.deviceDescriptor) != undefined))
53
+
54
+ it 'should have a configDescriptor property', ->
55
+ assert.ok(device.configDescriptor != undefined)
56
+
57
+ it 'should open', ->
58
+ device.open()
59
+
60
+ it 'gets string descriptors', (done) ->
61
+ device.getStringDescriptor device.deviceDescriptor.iManufacturer, (e, s) ->
62
+ assert.ok(e == undefined, e)
63
+ assert.equal(s, 'Nonolith Labs')
64
+ done()
65
+
66
+ describe 'control transfer', ->
67
+ b = Buffer.from([0x30...0x40])
68
+ it 'should OUT transfer when the IN bit is not set', (done) ->
69
+ device.controlTransfer 0x40, 0x81, 0, 0, b, (e) ->
70
+ assert.ok(e == undefined, e)
71
+ done()
72
+
73
+ it "should fail when bmRequestType doesn't match buffer / length", ->
74
+ assert.throws(-> device.controlTransfer(0x40, 0x81, 0, 0, 64))
75
+
76
+ it 'should IN transfer when the IN bit is set', (done) ->
77
+ device.controlTransfer 0xc0, 0x81, 0, 0, 128, (e, d) ->
78
+ #console.log("ControlTransferIn", d, e)
79
+ assert.ok(e == undefined, e)
80
+ assert.equal(d.toString(), b.toString())
81
+ done()
82
+
83
+ it 'should signal errors', (done) ->
84
+ device.controlTransfer 0xc0, 0xff, 0, 0, 64, (e, d) ->
85
+ assert.equal e.errno, usb.LIBUSB_TRANSFER_STALL
86
+ done()
87
+
88
+ describe 'Interface', ->
89
+ iface = null
90
+ before ->
91
+ iface = device.interfaces[0]
92
+ iface.claim()
93
+
94
+ it 'should have one interface', ->
95
+ assert.notEqual(iface, undefined)
96
+
97
+ it 'should be the same as the interfaceNo 0', ->
98
+ assert.strictEqual iface, device.interface(0)
99
+
100
+ if process.platform == 'linux'
101
+ it "shouldn't have a kernel driver", ->
102
+ assert.equal iface.isKernelDriverActive(), false
103
+
104
+ it "should fail to detach the kernel driver", ->
105
+ assert.throws -> iface.detachKernelDriver()
106
+
107
+ it "should fail to attach the kernel driver", ->
108
+ assert.throws -> iface.attachKernelDriver()
109
+
110
+ describe 'IN endpoint', ->
111
+ inEndpoint = null
112
+ before ->
113
+ inEndpoint = iface.endpoints[0]
114
+
115
+ it 'should be able to get the endpoint', ->
116
+ assert.ok inEndpoint?
117
+
118
+ it 'should be able to get the endpoint by address', ->
119
+ assert.equal(inEndpoint, iface.endpoint(0x81))
120
+
121
+ it 'should have the IN direction flag', ->
122
+ assert.equal(inEndpoint.direction, 'in')
123
+
124
+ it 'should have a descriptor', ->
125
+ assert.equal(inEndpoint.descriptor.bEndpointAddress, 0x81)
126
+ assert.equal(inEndpoint.descriptor.wMaxPacketSize, 64)
127
+
128
+ it 'should fail to write', ->
129
+ assert.throws -> inEndpoint.transfer(b)
130
+
131
+ it 'should support read', (done) ->
132
+ inEndpoint.transfer 64, (e, d) ->
133
+ assert.ok(e == undefined, e)
134
+ assert.ok(d.length == 64)
135
+ done()
136
+
137
+ it 'times out', (done) ->
138
+ iface.endpoints[2].timeout = 20
139
+ iface.endpoints[2].transfer 64, (e, d) ->
140
+ assert.equal e.errno, usb.LIBUSB_TRANSFER_TIMED_OUT
141
+ done()
142
+
143
+ it 'polls the device', (done) ->
144
+ pkts = 0
145
+
146
+ inEndpoint.startPoll 8, 64
147
+ inEndpoint.on 'data', (d) ->
148
+ assert.equal d.length, 64
149
+ pkts++
150
+
151
+ if pkts == 100
152
+ inEndpoint.stopPoll()
153
+
154
+ inEndpoint.on 'error', (e) ->
155
+ throw e
156
+
157
+ inEndpoint.on 'end', ->
158
+ #console.log("Stream stopped")
159
+ done()
160
+
161
+
162
+ describe 'OUT endpoint', ->
163
+ outEndpoint = null
164
+ before ->
165
+ outEndpoint = iface.endpoints[1]
166
+
167
+ it 'should be able to get the endpoint', ->
168
+ assert.ok outEndpoint?
169
+
170
+ it 'should be able to get the endpoint by address', ->
171
+ assert.equal(outEndpoint, iface.endpoint(0x02))
172
+
173
+ it 'should have the OUT direction flag', ->
174
+ assert.equal(outEndpoint.direction, 'out')
175
+
176
+ it 'should support write', (done) ->
177
+ outEndpoint.transfer [1,2,3,4], (e) ->
178
+ assert.ok(e == undefined, e)
179
+ done()
180
+
181
+ it 'times out', (done) ->
182
+ iface.endpoints[3].timeout = 20
183
+ iface.endpoints[3].transfer [1,2,3,4], (e) ->
184
+ assert.equal e.errno, usb.LIBUSB_TRANSFER_TIMED_OUT
185
+ done()
186
+
187
+ after (cb) ->
188
+ iface.release(cb)
189
+
190
+ after ->
191
+ device.close()
package/usb.js ADDED
@@ -0,0 +1,524 @@
1
+ var usb = exports = module.exports = require('node-gyp-build')(__dirname);
2
+ var events = require('events')
3
+ var util = require('util')
4
+
5
+ var isBuffer = function(obj) {
6
+ return obj && obj instanceof Uint8Array
7
+ }
8
+
9
+ if (usb.INIT_ERROR) {
10
+ console.warn("Failed to initialize libusb.")
11
+ usb.Device = function () { throw new Error("Device cannot be instantiated directly.") };
12
+ usb.Transfer = function () { throw new Error("Transfer cannot be instantiated directly.") };
13
+ usb.setDebugLevel = function () { };
14
+ usb.getDeviceList = function () { return []; };
15
+ usb._enableHotplugEvents = function () { };
16
+ usb._disableHotplugEvents = function () { };
17
+ }
18
+
19
+ Object.keys(events.EventEmitter.prototype).forEach(function (key) {
20
+ exports[key] = events.EventEmitter.prototype[key];
21
+ });
22
+
23
+ // convenience method for finding a device by vendor and product id
24
+ exports.findByIds = function(vid, pid) {
25
+ var devices = usb.getDeviceList()
26
+
27
+ for (var i = 0; i < devices.length; i++) {
28
+ var deviceDesc = devices[i].deviceDescriptor
29
+ if ((deviceDesc.idVendor == vid) && (deviceDesc.idProduct == pid)) {
30
+ return devices[i]
31
+ }
32
+ }
33
+ }
34
+
35
+ usb.Device.prototype.timeout = 1000
36
+
37
+ usb.Device.prototype.open = function(defaultConfig){
38
+ this.__open()
39
+ if (defaultConfig === false) return
40
+ this.interfaces = []
41
+ var len = this.configDescriptor ? this.configDescriptor.interfaces.length : 0
42
+ for (var i=0; i<len; i++){
43
+ this.interfaces[i] = new Interface(this, i)
44
+ }
45
+ }
46
+
47
+ usb.Device.prototype.close = function(){
48
+ this.__close()
49
+ this.interfaces = null
50
+ }
51
+
52
+ Object.defineProperty(usb.Device.prototype, "configDescriptor", {
53
+ get: function() {
54
+ try {
55
+ return this._configDescriptor || (this._configDescriptor = this.__getConfigDescriptor())
56
+ } catch(e) {
57
+ // Check descriptor exists
58
+ if (e.errno == usb.LIBUSB_ERROR_NOT_FOUND) return null;
59
+ throw e;
60
+ }
61
+ }
62
+ });
63
+
64
+ Object.defineProperty(usb.Device.prototype, "allConfigDescriptors", {
65
+ get: function() {
66
+ try {
67
+ return this._allConfigDescriptors || (this._allConfigDescriptors = this.__getAllConfigDescriptors())
68
+ } catch(e) {
69
+ // Check descriptors exist
70
+ if (e.errno == usb.LIBUSB_ERROR_NOT_FOUND) return [];
71
+ throw e;
72
+ }
73
+ }
74
+ });
75
+
76
+ Object.defineProperty(usb.Device.prototype, "parent", {
77
+ get: function() {
78
+ return this._parent || (this._parent = this.__getParent())
79
+ }
80
+ });
81
+
82
+ usb.Device.prototype.interface = function(addr){
83
+ if (!this.interfaces){
84
+ throw new Error("Device must be open before searching for interfaces")
85
+ }
86
+ addr = addr || 0
87
+ for (var i=0; i<this.interfaces.length; i++){
88
+ if (this.interfaces[i].interfaceNumber == addr){
89
+ return this.interfaces[i]
90
+ }
91
+ }
92
+ }
93
+
94
+ var SETUP_SIZE = usb.LIBUSB_CONTROL_SETUP_SIZE
95
+
96
+ usb.Device.prototype.controlTransfer =
97
+ function(bmRequestType, bRequest, wValue, wIndex, data_or_length, callback){
98
+ var self = this
99
+ var isIn = !!(bmRequestType & usb.LIBUSB_ENDPOINT_IN)
100
+ var wLength
101
+
102
+ if (isIn){
103
+ if (!(data_or_length >= 0)){
104
+ throw new TypeError("Expected size number for IN transfer (based on bmRequestType)")
105
+ }
106
+ wLength = data_or_length
107
+ }else{
108
+ if (!isBuffer(data_or_length)){
109
+ throw new TypeError("Expected buffer for OUT transfer (based on bmRequestType)")
110
+ }
111
+ wLength = data_or_length.length
112
+ }
113
+
114
+ // Buffer for the setup packet
115
+ // http://libusbx.sourceforge.net/api-1.0/structlibusb__control__setup.html
116
+ var buf = Buffer.alloc(wLength + SETUP_SIZE)
117
+ buf.writeUInt8( bmRequestType, 0)
118
+ buf.writeUInt8( bRequest, 1)
119
+ buf.writeUInt16LE(wValue, 2)
120
+ buf.writeUInt16LE(wIndex, 4)
121
+ buf.writeUInt16LE(wLength, 6)
122
+
123
+ if (!isIn){
124
+ buf.set(data_or_length, SETUP_SIZE)
125
+ }
126
+
127
+ var transfer = new usb.Transfer(this, 0, usb.LIBUSB_TRANSFER_TYPE_CONTROL, this.timeout,
128
+ function(error, buf, actual){
129
+ if (callback){
130
+ if (isIn){
131
+ callback.call(self, error, buf.slice(SETUP_SIZE, SETUP_SIZE + actual))
132
+ }else{
133
+ callback.call(self, error)
134
+ }
135
+ }
136
+ }
137
+ )
138
+
139
+ try {
140
+ transfer.submit(buf)
141
+ } catch (e) {
142
+ if (callback){
143
+ process.nextTick(function() { callback.call(self, e); });
144
+ }
145
+ }
146
+ return this;
147
+ }
148
+
149
+ usb.Device.prototype.getStringDescriptor = function (desc_index, callback) {
150
+ var langid = 0x0409;
151
+ var length = 255;
152
+ this.controlTransfer(
153
+ usb.LIBUSB_ENDPOINT_IN,
154
+ usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
155
+ ((usb.LIBUSB_DT_STRING << 8) | desc_index),
156
+ langid,
157
+ length,
158
+ function (error, buf) {
159
+ if (error) return callback(error);
160
+ callback(undefined, buf.toString('utf16le', 2));
161
+ }
162
+ );
163
+ }
164
+
165
+ usb.Device.prototype.getBosDescriptor = function (callback) {
166
+
167
+ if (this._bosDescriptor) {
168
+ // Cached descriptor
169
+ return callback(undefined, this._bosDescriptor);
170
+ }
171
+
172
+ if (this.deviceDescriptor.bcdUSB < 0x201) {
173
+ // BOS is only supported from USB 2.0.1
174
+ return callback(undefined, null);
175
+ }
176
+
177
+ this.controlTransfer(
178
+ usb.LIBUSB_ENDPOINT_IN,
179
+ usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
180
+ (usb.LIBUSB_DT_BOS << 8),
181
+ 0,
182
+ usb.LIBUSB_DT_BOS_SIZE,
183
+ function (error, buffer) {
184
+ if (error) {
185
+ // Check BOS descriptor exists
186
+ if (error.errno == usb.LIBUSB_TRANSFER_STALL) return callback(undefined, null);
187
+ return callback(error, null);
188
+ }
189
+
190
+ var totalLength = buffer.readUInt16LE(2);
191
+ this.controlTransfer(
192
+ usb.LIBUSB_ENDPOINT_IN,
193
+ usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
194
+ (usb.LIBUSB_DT_BOS << 8),
195
+ 0,
196
+ totalLength,
197
+ function (error, buffer) {
198
+ if (error) {
199
+ // Check BOS descriptor exists
200
+ if (error.errno == usb.LIBUSB_TRANSFER_STALL) return callback(undefined, null);
201
+ return callback(error, null);
202
+ }
203
+
204
+ var descriptor = {
205
+ bLength: buffer.readUInt8(0),
206
+ bDescriptorType: buffer.readUInt8(1),
207
+ wTotalLength: buffer.readUInt16LE(2),
208
+ bNumDeviceCaps: buffer.readUInt8(4),
209
+ capabilities: []
210
+ };
211
+
212
+ var i = usb.LIBUSB_DT_BOS_SIZE;
213
+ while (i < descriptor.wTotalLength) {
214
+ var capability = {
215
+ bLength: buffer.readUInt8(i + 0),
216
+ bDescriptorType: buffer.readUInt8(i + 1),
217
+ bDevCapabilityType: buffer.readUInt8(i + 2)
218
+ };
219
+
220
+ capability.dev_capability_data = buffer.slice(i + 3, i + capability.bLength);
221
+ descriptor.capabilities.push(capability);
222
+ i += capability.bLength;
223
+ }
224
+
225
+ // Cache descriptor
226
+ this._bosDescriptor = descriptor;
227
+ callback(undefined, this._bosDescriptor);
228
+ }
229
+ );
230
+ }
231
+ );
232
+ }
233
+
234
+ usb.Device.prototype.getCapabilities = function (callback) {
235
+ var capabilities = [];
236
+ var self = this;
237
+
238
+ this.getBosDescriptor(function(error, descriptor) {
239
+ if (error) return callback(error, null);
240
+
241
+ var len = descriptor ? descriptor.capabilities.length : 0
242
+ for (var i=0; i<len; i++){
243
+ capabilities.push(new Capability(self, i))
244
+ }
245
+
246
+ callback(undefined, capabilities);
247
+ });
248
+ }
249
+
250
+ usb.Device.prototype.setConfiguration = function(desired, cb) {
251
+ var self = this;
252
+ this.__setConfiguration(desired, function(err) {
253
+ if (!err) {
254
+ this.interfaces = []
255
+ var len = this.configDescriptor ? this.configDescriptor.interfaces.length : 0
256
+ for (var i=0; i<len; i++) {
257
+ this.interfaces[i] = new Interface(this, i)
258
+ }
259
+ }
260
+ cb.call(self, err)
261
+ });
262
+ }
263
+
264
+ function Interface(device, id){
265
+ this.device = device
266
+ this.id = id
267
+ this.altSetting = 0;
268
+ this.__refresh()
269
+ }
270
+
271
+ Interface.prototype.__refresh = function(){
272
+ this.descriptor = this.device.configDescriptor.interfaces[this.id][this.altSetting]
273
+ this.interfaceNumber = this.descriptor.bInterfaceNumber
274
+ this.endpoints = []
275
+ var len = this.descriptor.endpoints.length
276
+ for (var i=0; i<len; i++){
277
+ var desc = this.descriptor.endpoints[i]
278
+ var c = (desc.bEndpointAddress&usb.LIBUSB_ENDPOINT_IN)?InEndpoint:OutEndpoint
279
+ this.endpoints[i] = new c(this.device, desc)
280
+ }
281
+ }
282
+
283
+ Interface.prototype.claim = function(){
284
+ this.device.__claimInterface(this.id)
285
+ }
286
+
287
+ Interface.prototype.release = function(closeEndpoints, cb){
288
+ var self = this;
289
+ if (typeof closeEndpoints == 'function') {
290
+ cb = closeEndpoints;
291
+ closeEndpoints = null;
292
+ }
293
+
294
+ if (!closeEndpoints || this.endpoints.length == 0) {
295
+ next();
296
+ } else {
297
+ var n = self.endpoints.length;
298
+ self.endpoints.forEach(function (ep, i) {
299
+ if (ep.pollActive) {
300
+ ep.once('end', function () {
301
+ if (--n == 0) next();
302
+ });
303
+ ep.stopPoll();
304
+ } else {
305
+ if (--n == 0) next();
306
+ }
307
+ });
308
+ }
309
+
310
+ function next () {
311
+ self.device.__releaseInterface(self.id, function(err){
312
+ if (!err){
313
+ self.altSetting = 0;
314
+ self.__refresh()
315
+ }
316
+ cb.call(self, err)
317
+ })
318
+ }
319
+ }
320
+
321
+ Interface.prototype.isKernelDriverActive = function(){
322
+ return this.device.__isKernelDriverActive(this.id)
323
+ }
324
+
325
+ Interface.prototype.detachKernelDriver = function() {
326
+ return this.device.__detachKernelDriver(this.id)
327
+ };
328
+
329
+ Interface.prototype.attachKernelDriver = function() {
330
+ return this.device.__attachKernelDriver(this.id)
331
+ };
332
+
333
+
334
+ Interface.prototype.setAltSetting = function(altSetting, cb){
335
+ var self = this;
336
+ this.device.__setInterface(this.id, altSetting, function(err){
337
+ if (!err){
338
+ self.altSetting = altSetting;
339
+ self.__refresh();
340
+ }
341
+ cb.call(self, err)
342
+ })
343
+ }
344
+
345
+ Interface.prototype.endpoint = function(addr){
346
+ for (var i=0; i<this.endpoints.length; i++){
347
+ if (this.endpoints[i].address == addr){
348
+ return this.endpoints[i]
349
+ }
350
+ }
351
+ }
352
+
353
+ function Capability(device, id){
354
+ this.device = device
355
+ this.id = id
356
+ this.descriptor = this.device._bosDescriptor.capabilities[this.id]
357
+ this.type = this.descriptor.bDevCapabilityType
358
+ this.data = this.descriptor.dev_capability_data
359
+ }
360
+
361
+ function Endpoint(device, descriptor){
362
+ this.device = device
363
+ this.descriptor = descriptor
364
+ this.address = descriptor.bEndpointAddress
365
+ this.transferType = descriptor.bmAttributes&0x03
366
+ }
367
+ util.inherits(Endpoint, events.EventEmitter)
368
+
369
+ Endpoint.prototype.timeout = 0
370
+
371
+ Endpoint.prototype.clearHalt = function(callback){
372
+ return this.device.__clearHalt(this.address, callback);
373
+ }
374
+
375
+ Endpoint.prototype.makeTransfer = function(timeout, callback){
376
+ return new usb.Transfer(this.device, this.address, this.transferType, timeout, callback)
377
+ }
378
+
379
+ Endpoint.prototype.startPoll = function(nTransfers, transferSize, callback){
380
+ if (this.pollTransfers){
381
+ throw new Error("Polling already active")
382
+ }
383
+
384
+ nTransfers = nTransfers || 3;
385
+ this.pollTransferSize = transferSize || this.descriptor.wMaxPacketSize;
386
+ this.pollActive = true
387
+ this.pollPending = 0
388
+
389
+ var transfers = []
390
+ for (var i=0; i<nTransfers; i++){
391
+ transfers[i] = this.makeTransfer(0, callback)
392
+ }
393
+ return transfers;
394
+ }
395
+
396
+ Endpoint.prototype.stopPoll = function(cb){
397
+ if (!this.pollTransfers) {
398
+ throw new Error('Polling is not active.');
399
+ }
400
+ for (var i=0; i<this.pollTransfers.length; i++){
401
+ try {
402
+ this.pollTransfers[i].cancel()
403
+ } catch (err) {
404
+ this.emit('error', err);
405
+ }
406
+ }
407
+ this.pollActive = false
408
+ if (cb) this.once('end', cb);
409
+ }
410
+
411
+ function InEndpoint(device, descriptor){
412
+ Endpoint.call(this, device, descriptor)
413
+ }
414
+
415
+ exports.InEndpoint = InEndpoint
416
+ util.inherits(InEndpoint, Endpoint)
417
+ InEndpoint.prototype.direction = "in"
418
+
419
+ InEndpoint.prototype.transfer = function(length, cb){
420
+ var self = this
421
+ var buffer = Buffer.alloc(length)
422
+
423
+ function callback(error, buf, actual){
424
+ cb.call(self, error, buffer.slice(0, actual))
425
+ }
426
+
427
+ try {
428
+ this.makeTransfer(this.timeout, callback).submit(buffer)
429
+ } catch (e) {
430
+ process.nextTick(function() { cb.call(self, e); });
431
+ }
432
+ return this;
433
+ }
434
+
435
+ InEndpoint.prototype.startPoll = function(nTransfers, transferSize){
436
+ var self = this
437
+ this.pollTransfers = InEndpoint.super_.prototype.startPoll.call(this, nTransfers, transferSize, transferDone)
438
+
439
+ function transferDone(error, buf, actual){
440
+ if (!error){
441
+ self.emit("data", buf.slice(0, actual))
442
+ }else if (error.errno != usb.LIBUSB_TRANSFER_CANCELLED){
443
+ self.emit("error", error)
444
+ self.stopPoll()
445
+ }
446
+
447
+ if (self.pollActive){
448
+ startTransfer(this)
449
+ }else{
450
+ self.pollPending--
451
+
452
+ if (self.pollPending == 0){
453
+ delete self.pollTransfers;
454
+ self.emit('end')
455
+ }
456
+ }
457
+ }
458
+
459
+ function startTransfer(t){
460
+ try {
461
+ t.submit(Buffer.alloc(self.pollTransferSize), transferDone);
462
+ } catch (e) {
463
+ self.emit("error", e);
464
+ self.stopPoll();
465
+ }
466
+ }
467
+
468
+ this.pollTransfers.forEach(startTransfer)
469
+ self.pollPending = this.pollTransfers.length
470
+ }
471
+
472
+
473
+
474
+ function OutEndpoint(device, descriptor){
475
+ Endpoint.call(this, device, descriptor)
476
+ }
477
+ exports.OutEndpoint = OutEndpoint
478
+ util.inherits(OutEndpoint, Endpoint)
479
+ OutEndpoint.prototype.direction = "out"
480
+
481
+ OutEndpoint.prototype.transfer = function(buffer, cb){
482
+ var self = this
483
+ if (!buffer){
484
+ buffer = Buffer.alloc(0)
485
+ }else if (!isBuffer(buffer)){
486
+ buffer = Buffer.from(buffer)
487
+ }
488
+
489
+ function callback(error, buf, actual){
490
+ if (cb) cb.call(self, error)
491
+ }
492
+
493
+ try {
494
+ this.makeTransfer(this.timeout, callback).submit(buffer);
495
+ } catch (e) {
496
+ process.nextTick(function() { callback(e); });
497
+ }
498
+
499
+ return this;
500
+ }
501
+
502
+ OutEndpoint.prototype.transferWithZLP = function (buf, cb) {
503
+ if (buf.length % this.descriptor.wMaxPacketSize == 0) {
504
+ this.transfer(buf);
505
+ this.transfer(Buffer.alloc(0), cb);
506
+ } else {
507
+ this.transfer(buf, cb);
508
+ }
509
+ }
510
+
511
+ var hotplugListeners = 0;
512
+ exports.on('newListener', function(name) {
513
+ if (name !== 'attach' && name !== 'detach') return;
514
+ if (++hotplugListeners === 1) {
515
+ usb._enableHotplugEvents();
516
+ }
517
+ });
518
+
519
+ exports.on('removeListener', function(name) {
520
+ if (name !== 'attach' && name !== 'detach') return;
521
+ if (--hotplugListeners === 0) {
522
+ usb._disableHotplugEvents();
523
+ }
524
+ });