Removed some debugging output.

Implemented non-portable libusb functions.
Implemented force-claiming of interfaces (Only works when libusb supports detaching drivers)
This commit is contained in:
Klaus Reimer 2011-02-05 15:02:00 +01:00 committed by k
parent f49b05c57a
commit d80266929c
4 changed files with 188 additions and 13 deletions

View File

@ -72,7 +72,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(USB, usb_1get_1busses)
/**
* USB_Handle usb_open(USB_Device)
* USB_Dev_Handle usb_open(USB_Device)
*/
JNIEXPORT jobject JNICALL METHOD_NAME(USB, usb_1open)
@ -85,7 +85,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(USB, usb_1open)
/**
* int usb_close(USB_Handle)
* int usb_close(USB_Dev_Handle)
*/
JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1close)
@ -98,7 +98,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1close)
/**
* int usb_set_configuration(USB_Handle handle, int configuration)
* int usb_set_configuration(USB_Dev_Handle handle, int configuration)
*/
JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1set_1configuration)
@ -197,7 +197,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1control_1msg)
/**
* int usb_get_string(USB_Handle handle, int index, int langid, byte[] buffer,
* int usb_get_string(USB_Dev_Handle handle, int index, int langid, byte[] buffer,
* int buflen)
*/
@ -216,7 +216,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1get_1string)
/**
* int usb_get_simple_string(USB_Handle handle, int index, ByteBuffer buffer)
* int usb_get_simple_string(USB_Dev_Handle handle, int index, ByteBuffer buffer)
*/
JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1get_1string_1simple)
@ -357,3 +357,72 @@ JNIEXPORT jstring JNICALL METHOD_NAME(USB, usb_1strerror)
{
return (*env)->NewStringUTF(env, usb_strerror());
}
/**
* int usb_detach_kernel_driver_np(USB_Dev_Handle handle, int iface)
*/
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1detach_1kernel_1driver_1np)
(
JNIEnv *env, jclass class, jobject handle, jint iface
)
{
return usb_detach_kernel_driver_np(unwrap_usb_dev_handle(env, handle), iface);
}
#endif
/**
* int usb_get_driver_np(USB_Dev_Handle handle, int iface, ByteBuffer buffer)
*/
#ifdef LIBUSB_HAS_GET_DRIVER_NP
JNIEXPORT jint JNICALL METHOD_NAME(USB, usb_1get_1driver_1np)
(
JNIEnv *env, jclass class, jobject handle, jint iface, jobject buffer
)
{
void *buf = (*env)->GetDirectBufferAddress(env, buffer);
if (!buf) return -1;
jlong buflen = (*env)->GetDirectBufferCapacity(env, buffer);
return usb_get_driver_np(unwrap_usb_dev_handle(env, handle),
iface, buf, buflen);
}
#endif
/**
* boolean libusb_has_detach_kernel_driver_np()
*/
JNIEXPORT jboolean JNICALL METHOD_NAME(USB,
libusb_1has_1detach_1kernel_1driver_1np)
(
JNIEnv *env, jclass class
)
{
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
return 1;
#else
return 0;
#endif
}
/**
* boolean libusb_has_get_driver_np()
*/
JNIEXPORT jboolean JNICALL METHOD_NAME(USB, libusb_1has_1get_1driver_1np)
(
JNIEnv *env, jclass class
)
{
#ifdef LIBUSB_HAS_GET_DRIVER_NP
return 1;
#else
return 0;
#endif
}

View File

@ -764,4 +764,98 @@ public final class USB
*/
public static native String usb_strerror();
/**
* Get driver name bound to interface.
*
* This function will obtain the name of the driver bound to the interface
* specified by the parameter interface and place it into the specified
* buffer. Returns 0 on success or < 0 on error.
*
* Implemented on Linux only. On other platforms an UnsatisfiedLinkError
* exception will be thrown.
*
* @param handle
* The USB device handle.
* @param iface
* The interface number.
* @param buffer
* The buffer to place the name in.
* @return 0 on success or < 0 on error.
*/
public static native int usb_get_driver_np(USB_Dev_Handle handle,
int iface, ByteBuffer buffer);
/**
* Get driver name bound to interface.
*
* This function will obtain the name of the driver bound to the interface
* specified by the parameter interface.
*
* Implemented on Linux only. On other platforms an UnsatisfiedLinkError
* exception will be thrown.
*
* @param handle
* The USB device handle.
* @param iface
* The interface number.
* @return The driver name or null on error.
*/
public static String usb_get_driver_np(final USB_Dev_Handle handle,
final int iface)
{
final ByteBuffer buffer = ByteBuffer.allocateDirect(MAX_STRING_SIZE);
final int result = usb_get_driver_np(handle, iface, buffer);
if (result < 0) return null;
buffer.rewind();
int size = 0;
while (buffer.get() != 0) size++;
buffer.rewind();
final byte[] bytes = new byte[size];
buffer.get(bytes, 0, size);
return new String(bytes);
}
/**
* Detach kernel driver from interface.
*
* This function will detach a kernel driver from the interface specified by
* parameter interface. Applications using libusb can then try claiming the
* interface. Returns 0 on success or < 0 on error.
*
* Implemented on Linux only. On other platforms an UnsatisfiedLinkError
* exception will be thrown.
*
* @param handle
* The device handle.
* @param iface
* The interface number.
* @return 0 on success or < 0 on error.
*/
public static native int usb_detach_kernel_driver_np(USB_Dev_Handle handle,
int iface);
/**
* Checks if libusb supports the usb_get_driver_np function.
*
* @return True if support is present, false if not.
*/
public static native boolean libusb_has_get_driver_np();
/**
* Checks if libusb supports the usb_detach_kernel_driver_np function.
*
* @return True if support is present, false if not.
*/
public static native boolean libusb_has_detach_kernel_driver_np();
}

View File

@ -94,7 +94,6 @@ public final class UsbConfigurationImpl implements UsbConfiguration
desc.bAlternateSetting() == 0)
{
this.activeSettings.put(ifaceNumber, usbInterface);
System.out.println("Active: " + usbInterface);
}
// Add the interface to the settings list

View File

@ -5,6 +5,9 @@
package de.ailis.usb4java.jsr80;
import static de.ailis.usb4java.USB.libusb_has_detach_kernel_driver_np;
import static de.ailis.usb4java.USB.usb_detach_kernel_driver_np;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
@ -43,11 +46,14 @@ public final class UsbInterfaceImpl implements UsbInterface
/** The endpoint address to endpoints mapping. */
private final Map<Byte, UsbEndpoint> endpointMap =
new HashMap<Byte, UsbEndpoint>();
new HashMap<Byte, UsbEndpoint>();
/** The endpoints. */
private final List<UsbEndpoint> endpoints;
/** The USB device. */
private final AbstractDevice device;
/**
* Constructor.
@ -66,15 +72,16 @@ public final class UsbInterfaceImpl implements UsbInterface
{
this.configuration = configuration;
this.descriptor = new UsbInterfaceDescriptorImpl(lowLevelDescriptor);
this.device = device;
final List<UsbEndpoint> endpoints = new ArrayList<UsbEndpoint>();
for (final USB_Endpoint_Descriptor desc : lowLevelDescriptor
.endpoint())
.endpoint())
{
final UsbEndpointDescriptor descriptor =
new UsbEndpointDescriptorImpl(desc);
new UsbEndpointDescriptorImpl(desc);
final UsbEndpoint endpoint =
new UsbEndpointImpl(this, descriptor, device);
new UsbEndpointImpl(this, descriptor, device);
this.endpointMap.put(descriptor.bEndpointAddress(), endpoint);
endpoints.add(endpoint);
}
@ -131,6 +138,15 @@ public final class UsbInterfaceImpl implements UsbInterface
USBLock.acquire();
try
{
// Detach existing driver from the device if requested and
// libusb supports it.
if (policy != null && policy.forceClaim(this)
&& libusb_has_detach_kernel_driver_np())
{
usb_detach_kernel_driver_np(this.device.open(),
this.descriptor.bInterfaceNumber());
}
device.setActiveUsbConfigurationNumber(this.configuration
.getUsbConfigurationDescriptor().bConfigurationValue());
device.claimInterface(this.descriptor.bInterfaceNumber());
@ -175,9 +191,6 @@ public final class UsbInterfaceImpl implements UsbInterface
@Override
public boolean isActive()
{
System.out.println(this.configuration.getUsbInterface(this.descriptor
.bInterfaceNumber()));
System.out.println(this);
return this.configuration.getUsbInterface(this.descriptor
.bInterfaceNumber()) == this;
}