libusb 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/libusb/bos.rb CHANGED
@@ -19,7 +19,7 @@ module LIBUSB
19
19
  # A structure representing the Binary Device Object Store (BOS) descriptor.
20
20
  # This descriptor is documented in section 9.6.2 of the USB 3.0 specification.
21
21
  # All multiple-byte fields are represented in host-endian format.
22
- class Bos < FFI::ManagedStruct
22
+ class Bos < FFI::Struct
23
23
 
24
24
  module GenericMethods
25
25
  # @return [Integer] Size of this descriptor (in bytes)
@@ -39,7 +39,7 @@ module LIBUSB
39
39
  end
40
40
 
41
41
  def inspect
42
- "\#<#{self.class} cap: #{bDevCapabilityType} data: #{dev_capability_data.unpack("H*")[0]}>"
42
+ "\#<#{self.class} cap: #{bDevCapabilityType} data: #{dev_capability_data.unpack1("H*")}>"
43
43
  end
44
44
 
45
45
  # @return [String] Device Capability data (bLength - 3 bytes)
@@ -66,14 +66,21 @@ module LIBUSB
66
66
  # A structure representing the USB 2.0 Extension descriptor
67
67
  # This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification.
68
68
  # All multiple-byte fields are represented in host-endian format.
69
- class Usb20Extension < FFI::ManagedStruct
69
+ class Usb20Extension < FFI::Struct
70
70
  include GenericMethods
71
+ include ContextReference
71
72
 
72
73
  layout :bLength, :uint8,
73
74
  :bDescriptorType, :uint8,
74
75
  :bDevCapabilityType, :uint8,
75
76
  :bmAttributes, :uint32
76
77
 
78
+ def initialize(ctx, *args)
79
+ super(*args)
80
+
81
+ register_context(ctx, :libusb_free_usb_2_0_extension_descriptor)
82
+ end
83
+
77
84
  # Bitmap encoding of supported device level features.
78
85
  # A value of one in a bit location indicates a feature is
79
86
  # supported; a value of zero indicates it is not supported.
@@ -93,28 +100,30 @@ module LIBUSB
93
100
  end
94
101
  "\#<#{self.class} #{attrs.compact.join(",")}>"
95
102
  end
96
-
97
- # @private
98
- def self.release(ptr)
99
- Call.libusb_free_usb_2_0_extension_descriptor(ptr)
100
- end
101
103
  end
102
104
 
103
105
  # A structure representing the SuperSpeed USB Device Capability descriptor
104
106
  # This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification.
105
107
  # All multiple-byte fields are represented in host-endian format.
106
- class SsUsbDeviceCapability < FFI::ManagedStruct
108
+ class SsUsbDeviceCapability < FFI::Struct
107
109
  include GenericMethods
110
+ include ContextReference
108
111
 
109
112
  layout :bLength, :uint8,
110
113
  :bDescriptorType, :uint8,
111
114
  :bDevCapabilityType, :uint8,
112
- :bmAttributes, :uint32,
115
+ :bmAttributes, :uint8,
113
116
  :wSpeedSupported, :uint16,
114
117
  :bFunctionalitySupport, :uint8,
115
118
  :bU1DevExitLat, :uint8,
116
119
  :bU2DevExitLat, :uint16
117
120
 
121
+ def initialize(ctx, *args)
122
+ super(*args)
123
+
124
+ register_context(ctx, :libusb_free_ss_usb_device_capability_descriptor)
125
+ end
126
+
118
127
  # Bitmap encoding of supported device level features.
119
128
  # A value of one in a bit location indicates a feature is
120
129
  # supported; a value of zero indicates it is not supported.
@@ -178,18 +187,14 @@ module LIBUSB
178
187
  def bU2DevExitLat
179
188
  self[:bU2DevExitLat]
180
189
  end
181
-
182
- # @private
183
- def self.release(ptr)
184
- Call.libusb_free_ss_usb_device_capability_descriptor(ptr)
185
- end
186
190
  end
187
191
 
188
192
  # A structure representing the Container ID descriptor.
189
193
  # This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification.
190
194
  # All multiple-byte fields, except UUIDs, are represented in host-endian format.
191
- class ContainerId < FFI::ManagedStruct
195
+ class ContainerId < FFI::Struct
192
196
  include GenericMethods
197
+ include ContextReference
193
198
 
194
199
  layout :bLength, :uint8,
195
200
  :bDescriptorType, :uint8,
@@ -197,6 +202,12 @@ module LIBUSB
197
202
  :bReserved, :uint8,
198
203
  :ContainerID, [:uint8, 16]
199
204
 
205
+ def initialize(ctx, *args)
206
+ super(*args)
207
+
208
+ register_context(ctx, :libusb_free_container_id_descriptor)
209
+ end
210
+
200
211
  # Reserved field
201
212
  def bReserved
202
213
  self[:bReserved]
@@ -208,18 +219,65 @@ module LIBUSB
208
219
  end
209
220
 
210
221
  def inspect
211
- "\#<#{self.class} #{container_id.unpack("H*")[0]}>"
222
+ "\#<#{self.class} #{container_id.unpack1("H*")}>"
223
+ end
224
+ end
225
+
226
+
227
+ # A structure representing a Platform descriptor.
228
+ # This descriptor is documented in section 9.6.2.4 of the USB 3.2 specification.
229
+ class PlatformDescriptor < FFI::Struct
230
+ include GenericMethods
231
+ include ContextReference
232
+
233
+ layout :bLength, :uint8,
234
+ :bDescriptorType, :uint8,
235
+ # Capability type. Will have value
236
+ # libusb_capability_type::LIBUSB_BT_PLATFORM_DESCRIPTOR
237
+ # LIBUSB_BT_CONTAINER_ID in this context.
238
+ :bDevCapabilityType, :uint8,
239
+ # Reserved field
240
+ :bReserved, :uint8,
241
+ # 128 bit UUID
242
+ :PlatformCapabilityUUID, [:uint8, 16],
243
+ # Capability data (bLength - 20)
244
+ :CapabilityData, [:uint8, 0]
245
+
246
+ def initialize(ctx, *args)
247
+ super(*args)
248
+
249
+ register_context(ctx, :libusb_free_platform_descriptor)
250
+ end
251
+
252
+ # Reserved field
253
+ def bReserved
254
+ self[:bReserved]
255
+ end
256
+
257
+ # @return [String] 128 bit UUID
258
+ def platformCapabilityUUID
259
+ self[:PlatformCapabilityUUID].to_ptr.read_bytes(16)
212
260
  end
213
261
 
214
- # @private
215
- def self.release(ptr)
216
- Call.libusb_free_container_id_descriptor(ptr)
262
+ # This is a variable-length field containing data associated with the platform specific capability.
263
+ # This field may be zero bytes in length.
264
+ # @return [String]
265
+ def capabilityData
266
+ self[:CapabilityData].to_ptr.read_bytes(bLength - 20)
267
+ end
268
+
269
+ def inspect
270
+ "\#<#{self.class} #{platformCapabilityUUID.unpack1("H*")} (#{capabilityData.unpack1("H*")})>"
217
271
  end
218
272
  end
219
273
 
220
- def initialize( ctx, *args)
274
+ include ContextReference
275
+
276
+ def initialize(ctx, *args)
221
277
  @ctx = ctx
222
278
  super(*args)
279
+
280
+ register_context(ctx, :libusb_free_bos_descriptor)
223
281
  end
224
282
 
225
283
  layout :bLength, :uint8,
@@ -265,13 +323,16 @@ module LIBUSB
265
323
  # no struct defined in libusb -> use generic DeviceCapability
266
324
  when LIBUSB::BT_USB_2_0_EXTENSION
267
325
  res = Call.libusb_get_usb_2_0_extension_descriptor(@ctx, cap.pointer, pp_ext)
268
- cap = Usb20Extension.new(pp_ext.read_pointer) if res==0
326
+ cap = Usb20Extension.new(@ctx, pp_ext.read_pointer) if res==0
269
327
  when LIBUSB::BT_SS_USB_DEVICE_CAPABILITY
270
328
  res = Call.libusb_get_ss_usb_device_capability_descriptor(@ctx, cap.pointer, pp_ext)
271
- cap = SsUsbDeviceCapability.new(pp_ext.read_pointer) if res==0
329
+ cap = SsUsbDeviceCapability.new(@ctx, pp_ext.read_pointer) if res==0
272
330
  when LIBUSB::BT_CONTAINER_ID
273
331
  res = Call.libusb_get_container_id_descriptor(@ctx, cap.pointer, pp_ext)
274
- cap = ContainerId.new(pp_ext.read_pointer) if res==0
332
+ cap = ContainerId.new(@ctx, pp_ext.read_pointer) if res==0
333
+ when LIBUSB::BT_PLATFORM_DESCRIPTOR
334
+ res = Call.libusb_get_platform_descriptor(@ctx, cap.pointer, pp_ext)
335
+ cap = PlatformDescriptor.new(@ctx, pp_ext.read_pointer) if res==0
275
336
  else
276
337
  # unknown capability -> use generic DeviceCapability
277
338
  end
@@ -297,10 +358,5 @@ module LIBUSB
297
358
  def inspect
298
359
  "\#<#{self.class} #{device_capability_types.join(", ")}>"
299
360
  end
300
-
301
- # @private
302
- def self.release(ptr)
303
- Call.libusb_free_bos_descriptor(ptr)
304
- end
305
361
  end
306
362
  end
data/lib/libusb/call.rb CHANGED
@@ -228,14 +228,23 @@ module LIBUSB
228
228
  #
229
229
  # @see Bos::DeviceCapability
230
230
  BosTypes = enum :libusb_bos_type, [
231
- # Wireless USB device capability
232
- :BT_WIRELESS_USB_DEVICE_CAPABILITY, 1,
233
- # USB 2.0 extensions
234
- :BT_USB_2_0_EXTENSION, 2,
235
- # SuperSpeed USB device capability
236
- :BT_SS_USB_DEVICE_CAPABILITY, 3,
237
- # Container ID type
238
- :BT_CONTAINER_ID, 4,
231
+ :BT_WIRELESS_USB_DEVICE_CAPABILITY, 0x01, # Wireless USB device capability
232
+ :BT_USB_2_0_EXTENSION, 0x02, # USB 2.0 extensions
233
+ :BT_SS_USB_DEVICE_CAPABILITY, 0x03, # SuperSpeed USB device capability
234
+ :BT_CONTAINER_ID, 0x04, # Container ID type
235
+ :BT_PLATFORM_DESCRIPTOR, 0x05, # Platform descriptor
236
+ :BT_POWER_DELIVERY_CAPABILITY, 0x06, # Defines the various PD Capabilities of this device
237
+ :BT_BATTERY_INFO_CAPABILITY, 0x07, # Provides information on each battery supported by the device
238
+ :BT_PD_CONSUMER_PORT_CAPABILITY, 0x08, # The consumer characteristics of a port on the device
239
+ :BT_PD_PROVIDER_PORT_CAPABILITY, 0x09, # The provider characteristics of a port on the device
240
+ :BT_SUPERSPEED_PLUS, 0x0A, # Defines the set of SuperSpeed Plus USB specific device level capabilities
241
+ :BT_PRECISION_TIME_MEASUREMENT, 0x0B, # Precision Time Measurement (PTM) Capability Descriptor
242
+ :BT_Wireless_USB_Ext, 0x0C, # Defines the set of Wireless USB 1.1-specific device level capabilities
243
+ :BT_BILLBOARD, 0x0D, # Billboard capability
244
+ :BT_AUTHENTICATION, 0x0E, # Authentication Capability Descriptor
245
+ :BT_BILLBOARD_EX, 0x0F, # Billboard Ex capability
246
+ :BT_CONFIGURATION_SUMMARY, 0x10, # Summarizes configuration information for a function implemented by the device
247
+ :BT_FWStatus_Capability, 0x11, # Describes the capability to support FWStatus
239
248
  ]
240
249
 
241
250
  # Since libusb version 1.0.16.
@@ -274,6 +283,25 @@ module LIBUSB
274
283
  :LOG_LEVEL_DEBUG, 4,
275
284
  ]
276
285
 
286
+ # /** \ingroup libusb_lib
287
+ # * Log callback mode.
288
+ # *
289
+ # * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
290
+ # *
291
+ # * \see libusb_set_log_cb()
292
+ # */
293
+ # enum libusb_log_cb_mode {
294
+ # /** Callback function handling all log messages. */
295
+ # LIBUSB_LOG_CB_GLOBAL = (1 << 0),
296
+ #
297
+ # /** Callback function handling context related log messages. */
298
+ # LIBUSB_LOG_CB_CONTEXT = (1 << 1)
299
+ # };
300
+ LogCbMode = enum :libusb_log_cb_mode, [
301
+ :LOG_CB_GLOBAL, (1 << 0),
302
+ :LOG_CB_CONTEXT, (1 << 1),
303
+ ]
304
+
277
305
  # Available option values for {Context#set_option}.
278
306
  Options = enum :libusb_option, [
279
307
  # Set the log message verbosity.
@@ -296,7 +324,7 @@ module LIBUSB
296
324
  #
297
325
  # If libusb was compiled with verbose debug message logging, this function
298
326
  # does nothing: you'll always get messages from all levels.
299
- :OPTION_LOG_LEVEL,
327
+ :OPTION_LOG_LEVEL, 0,
300
328
 
301
329
  # Use the UsbDk backend for a specific context, if available.
302
330
  #
@@ -306,7 +334,33 @@ module LIBUSB
306
334
  # Only valid on Windows.
307
335
  #
308
336
  # Available since libusb-1.0.22.
309
- :OPTION_USE_USBDK,
337
+ :OPTION_USE_USBDK, 1,
338
+
339
+ # Do not scan for devices
340
+ #
341
+ # With this option set, libusb will skip scanning devices in
342
+ # libusb_init_context().
343
+ #
344
+ # Hotplug functionality will also be deactivated.
345
+ #
346
+ # The option is useful in combination with libusb_wrap_sys_device(),
347
+ # which can access a device directly without prior device scanning.
348
+ #
349
+ # This is typically needed on Android, where access to USB devices
350
+ # is limited.
351
+ #
352
+ # Only valid on Linux. Ignored on all other platforms.
353
+ :OPTION_NO_DEVICE_DISCOVERY, 2,
354
+
355
+ # Set the context log callback functon.
356
+ #
357
+ # Set the log callback function either on a context or globally.
358
+ # This option must be provided a Proc argument or +nil+ to remove the callback.
359
+ # Using this option with a +nil+ context is equivalent to calling libusb_set_log_cb with mode :LOG_CB_GLOBAL.
360
+ # Using it with a non- +nil+ context is equivalent to calling libusb_set_log_cb with mode :LOG_CB_CONTEXT.
361
+ :OPTION_LOG_CB, 3,
362
+
363
+ :OPTION_MAX, 4,
310
364
  ]
311
365
 
312
366
  typedef :pointer, :libusb_context
@@ -315,15 +369,60 @@ module LIBUSB
315
369
  typedef :pointer, :libusb_transfer
316
370
  typedef :int, :libusb_hotplug_callback_handle
317
371
 
318
- def self.try_attach_function(method, *args)
319
- if ffi_libraries.find{|lib| lib.find_function(method) }
320
- attach_function method, *args
372
+ # /** \ingroup libusb_lib
373
+ # * Callback function for handling log messages.
374
+ # * \param ctx the context which is related to the log message, or +nil+ if it
375
+ # * is a global log message
376
+ # * \param level the log level, see \ref libusb_log_level for a description
377
+ # * \param str the log message
378
+ # *
379
+ # * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
380
+ # *
381
+ # * \see libusb_set_log_cb()
382
+ # */
383
+ # typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx,
384
+ # enum libusb_log_level level, const char *str);
385
+ callback :libusb_log_cb, [:libusb_context, :libusb_log_level, :string], :void
386
+
387
+ # @private
388
+ # /** \ingroup libusb_lib
389
+ # * Structure used for setting options through \ref libusb_init_context.
390
+ # *
391
+ # */
392
+ # struct libusb_init_option {
393
+ # /** Which option to set */
394
+ # enum libusb_option option;
395
+ # /** An integer value used by the option (if applicable). */
396
+ # union {
397
+ # int64_t ival;
398
+ # libusb_log_cb log_cbval;
399
+ # } value;
400
+ # };
401
+ class InitOptionValue < FFI::Union
402
+ layout :ival, :int64_t,
403
+ :log_cbval, :libusb_log_cb
404
+ end
405
+ class InitOption < FFI::Struct
406
+ layout :option, :libusb_option,
407
+ :value, InitOptionValue
408
+ end
409
+
410
+ class << self
411
+ private def try_attach_function(method, *args, **kwargs)
412
+ if ffi_libraries.find{|lib| lib.find_function(method) }
413
+ attach_function method, *args, **kwargs
414
+ end
321
415
  end
322
416
  end
323
417
 
324
418
  try_attach_function 'libusb_get_version', [], :pointer
325
419
 
326
420
  attach_function 'libusb_init', [ :pointer ], :int
421
+ # int LIBUSB_CALL libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options);
422
+ try_attach_function 'libusb_init_context', [:pointer, :pointer, :int], :int
423
+ # may be deprecated in the future in favor of libusb_init_context()+libusb_set_option()
424
+ # void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode);
425
+ try_attach_function 'libusb_set_log_cb', [:libusb_context, :libusb_log_cb, :int], :void
327
426
  attach_function 'libusb_exit', [ :pointer ], :void
328
427
  attach_function 'libusb_set_debug', [:pointer, :libusb_log_level], :void
329
428
  try_attach_function 'libusb_set_option', [:libusb_context, :libusb_option, :varargs], :int
@@ -348,6 +447,8 @@ module LIBUSB
348
447
  try_attach_function 'libusb_get_device_speed', [:pointer], :libusb_speed
349
448
  attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
350
449
  attach_function 'libusb_get_max_iso_packet_size', [:pointer, :uint8], :int
450
+ # int API_EXPORTED libusb_get_max_alt_packet_size(libusb_device *dev, int interface_number, int alternate_setting, unsigned char endpoint)
451
+ try_attach_function 'libusb_get_max_alt_packet_size', [:pointer, :int, :int, :uchar], :int
351
452
 
352
453
  try_attach_function 'libusb_get_ss_endpoint_companion_descriptor', [:pointer, :pointer, :pointer], :int
353
454
  try_attach_function 'libusb_free_ss_endpoint_companion_descriptor', [:pointer], :void
@@ -360,7 +461,11 @@ module LIBUSB
360
461
  try_attach_function 'libusb_free_ss_usb_device_capability_descriptor', [:pointer], :void
361
462
  try_attach_function 'libusb_get_container_id_descriptor', [:libusb_context, :pointer, :pointer], :int
362
463
  try_attach_function 'libusb_free_container_id_descriptor', [:pointer], :void
464
+ try_attach_function 'libusb_get_platform_descriptor', [:libusb_context, :pointer, :pointer], :int
465
+ try_attach_function 'libusb_free_platform_descriptor', [:pointer], :void
363
466
 
467
+ # int LIBUSB_CALL libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle);
468
+ try_attach_function 'libusb_wrap_sys_device', [:libusb_context, :intptr_t, :pointer], :int
364
469
  attach_function 'libusb_open', [:pointer, :pointer], :int
365
470
  attach_function 'libusb_close', [:pointer], :void
366
471
  attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
@@ -431,7 +536,7 @@ module LIBUSB
431
536
  :wLength, :uint16
432
537
  end
433
538
 
434
- class Transfer < FFI::ManagedStruct
539
+ class Transfer < FFI::Struct
435
540
  layout :dev_handle, :libusb_device_handle,
436
541
  :flags, :uint8,
437
542
  :endpoint, :uchar,
@@ -445,8 +550,19 @@ module LIBUSB
445
550
  :buffer, :pointer,
446
551
  :num_iso_packets, :int
447
552
 
448
- def self.release(ptr)
449
- Call.libusb_free_transfer(ptr)
553
+ def initialize(*)
554
+ super
555
+
556
+ ptr = pointer
557
+ def ptr.free_struct(id)
558
+ Call.libusb_free_transfer(self)
559
+ return unless @ctx
560
+ @ctx.unref_context
561
+ end
562
+ # The ctx pointer is not yet assigned.
563
+ # It happens at LIBUSB::Transfer#dev_handle= later on.
564
+ ptr.instance_variable_set(:@ctx, nil)
565
+ ObjectSpace.define_finalizer(self, ptr.method(:free_struct))
450
566
  end
451
567
  end
452
568
 
@@ -16,8 +16,9 @@
16
16
  require 'libusb/call'
17
17
 
18
18
  module LIBUSB
19
- class Configuration < FFI::ManagedStruct
19
+ class Configuration < FFI::Struct
20
20
  include Comparable
21
+ include ContextReference
21
22
 
22
23
  layout :bLength, :uint8,
23
24
  :bDescriptorType, :uint8,
@@ -108,10 +109,8 @@ module LIBUSB
108
109
  def initialize(device, *args)
109
110
  @device = device
110
111
  super(*args)
111
- end
112
112
 
113
- def self.release(ptr)
114
- Call.libusb_free_config_descriptor(ptr)
113
+ register_context(device.context.instance_variable_get(:@ctx), :libusb_free_config_descriptor)
115
114
  end
116
115
 
117
116
  # @return [Device] the device this configuration belongs to.
@@ -34,6 +34,7 @@ module LIBUSB
34
34
  Call::HotplugEvents,
35
35
  Call::HotplugFlags,
36
36
  Call::LogLevels,
37
+ Call::LogCbMode,
37
38
  Call::Options,
38
39
  ].each do |enum|
39
40
  enum.to_h.each{|k,v| const_set(k,v) }
@@ -52,6 +53,9 @@ module LIBUSB
52
53
  end
53
54
  end
54
55
 
56
+ class RemainingReferencesError < Error
57
+ end
58
+
55
59
  # @private
56
60
  ErrorClassForResult = {}
57
61