📄 deviceimpl.java
字号:
}
/**
* Assigns a device configuration, which must be one of those
* supported by this device. The kernel assigned one already.
*
* @deprecated
* <em><font color=red>Consider this dangerous.</font></em>
* At this writing, neither this
* package nor the kernel seems to handle the state already
* associated with the active interfaces. It all should get
* cleanly shut down before doing SET_CONFIGURATION.
*/
public void setConfiguration (int index)
throws USBException
{
int status;
if (index < 0 || index > descriptor.getNumConfigurations ())
throw new IllegalArgumentException ();
synchronized (lock) {
if ((status = setConfiguration (fd, index)) < 0)
throw new USBException ("can't set configuration", -status);
if (selectedConfig != index) {
selectedConfig = index;
currentConfig = null;
}
}
}
// usbdevfs-imposed limitation; USB limit is 64KB
private static final int MAX_CONTROL_LENGTH = 4096;
public byte [] readControl (byte type, byte request,
short value, short index, short length)
throws IOException
{
byte data [] = new byte [length & 0xffff];
int status;
if (length >= MAX_CONTROL_LENGTH
|| (type & ControlMessage.DIR_TO_HOST) == 0)
throw new IllegalArgumentException ();
if (Linux.trace)
System.out.println (
"Dev.readControl, rqt 0x" + Integer.toHexString (0xff & type)
+ ", req 0x" + Integer.toHexString (0xff & request)
+ ", value 0x" + Integer.toHexString (0xffff & value)
+ ", index 0x" + Integer.toHexString (0xffff & index)
+ ", len " + Integer.toString (0xffff & length)
);
status = controlMsg (fd, type, request, value, index,
data, 0, (short) data.length);
if (status >= 0) {
if (status != data.length) {
byte temp [] = new byte [status];
System.arraycopy (data, 0, temp, 0, status);
data = temp;
}
return data;
}
throw new USBException ("control read error", -status);
}
public void writeControl (byte type, byte request,
short value, short index, byte buf [])
throws IOException
{
if (buf.length >= MAX_CONTROL_LENGTH
|| (type & ControlMessage.DIR_TO_HOST) != 0)
throw new IllegalArgumentException ();
if (Linux.trace)
System.out.println (
"Dev.writeControl, rqt 0x" + Integer.toHexString (0xff & type)
+ ", req 0x" + Integer.toHexString (0xff & request)
+ ", value 0x" + Integer.toHexString (0xffff & value)
+ ", index 0x" + Integer.toHexString (0xffff & index)
+ ", len " + Integer.toString (buf.length)
);
int status = controlMsg (fd, type, request, value, index,
buf, 0, (short) buf.length);
if (status < 0)
throw new USBException ("control write error", -status);
}
public byte [] getConfigBuf (int n)
throws IOException
{
byte buf [];
Configuration config;
int total;
// start by reading just the configuration descriptor
buf = ControlMessage.getStandardDescriptor (this,
Descriptor.TYPE_CONFIGURATION,
(byte) n, 0, 9);
config = new Configuration (this, buf);
// return ALL descriptors (interface, endpoint, ...)
if ((total = config.getTotalLength ()) != buf.length) {
// WATCH FOR: devs not handling this post-enumeration
buf = ControlMessage.getStandardDescriptor (this,
Descriptor.TYPE_CONFIGURATION,
(byte) n, 0, total);
}
return buf;
}
/*-------------------------------------------------------------------*/
/*
* Native code support.
* All these methods return negative errno on error.
*
* Since most of them use ioctl(), which "green" threads doesn't wrap,
* you should use "-native" threading when you start your JVM.
* EINTR seems to mean "use native threads!".
*/
/** Connects to preliminary usbdevfs device state */
private int fd;
/** Opens the usb devfs file. */
private static native int openNative (String filename);
/** Closes the native file descriptor. */
private static native int closeNative (int fd);
private static native int controlMsg (int fd,
byte requestType, byte request,
short value, short index,
byte buf [], int off, short length);
/** Assigns the specified configuration as current. */
private static native int setConfiguration (int fd, int config);
// XXX some of these I/O methods should pass timeouts
// to support some sort of clean activity shutdown
// (policy in the Java layer, not inside this JNI glue)
// (glue policy is a 10 second timeout at this writing)
private static native int readBulk (int fd, int ep,
byte buf [], int off, int length);
// this is the API imposed by RMI.
// forces an extra rx copy, also heap access
public byte [] readBulk (int ep, int length)
throws IOException
{
byte retval [] = new byte [length];
int result = readBulk (ep, retval, 0, length);
if (result < 0)
throw new USBException ("readBulk", -result);
if (result != length) {
byte temp [] = new byte [result];
System.arraycopy (retval, 0, temp, 0, result);
retval = temp;
}
return retval;
}
// this is the API we'd LIKE to use:
// minimum # copies, heap is left alone
public int readBulk (int ep, byte buf [], int off, int length)
{
// devfs currently maxes out at 4KB bulk transfers
int result = 0;
while (length > 0) {
int this_transfer = Math.min (length, 4096);
int temp = readBulk (fd, ep, buf, off, this_transfer);
// error ... discarding how much we've read
if (temp < 0)
return temp;
off += temp;
length -= temp;
result += temp;
// short reads should return
if (temp < this_transfer)
break;
}
return result;
}
private static native int writeBulk (int fd, int ep,
byte buf [], int off, int length);
// this is the API imposed by RMI.
// usually forces an extra tx copy, and heap access
public void
writeBulk (int ep, byte buf [])
throws USBException
{ writeBulk (ep, buf, 0, buf.length); }
// this is the API we'd LIKE to use:
// minimum # copies, heap is left alone
public void
writeBulk (int ep, byte buf [], int off, int length)
throws USBException
{
// devfs currently maxes out at 4KB bulk transfers
int result = 0;
while (length > 0) {
int this_transfer = Math.min (length, 4096);
result = writeBulk (fd, ep, buf, off, this_transfer);
if (result < 0)
throw new USBException ("writeBulk", -result);
off += this_transfer;
length -= this_transfer;
}
}
private static native int readIntr (int fd, int ep,
byte buf [], int off, int length);
public byte [] readIntr (int ep, int length)
{
byte retval [] = new byte [length];
int len = readBulk (fd, ep, retval, 0, length);
// int len = readIntr (fd, ep, retval, 0, length);
if (len != length) {
byte temp [] = new byte [len];
System.arraycopy (retval, 0, temp, 0, len);
retval = temp;
}
return retval;
}
private static native int writeIntr (int fd, int ep,
byte buf [], int off, int length);
public void
writeIntr (int ep, byte buf [])
throws USBException
{
// int retval = writeIntr (fd, ep, buf, 0, buf.length);
int retval = writeBulk (fd, ep, buf, 0, buf.length);
if (retval < 0)
throw new USBException ("writeIntr", -retval);
}
private static native int clearHalt (int fd, byte ep);
// package private
public
int clearHalt (byte ep) { return clearHalt (fd, ep); }
private static native int claimInterface (int fd, int ifno);
/**
* Claims this interface, so that no other driver can.
*/
public void claimInterface (int ifno)
throws IOException
{
int val = claimInterface (fd, ifno);
if (val < 0)
throw new USBException ("claimInterface", -val);
}
// usbdevfs is done using this interface
private static native int releaseInterface (int fd, int ifno);
/**
* Releases an interface claim.
*/
public void releaseInterface (int ifno)
throws IOException
{
int val = releaseInterface (fd, ifno);
if (val < 0)
throw new USBException ("releaseInterface", -val);
}
private static native int setInterface (int fd, int ifno, int alt);
/**
* Assigns an interface to an alternate setting.
* <em>Note:</em> alternate settings probably
* aren't handled correctly yet.
*/
public void setInterface (int ifno, int alt)
throws IOException
{
int val = setInterface (fd, ifno, alt);
if (val < 0)
throw new USBException ("setInterface", -val);
}
private static native int getHubPorts (int fd, byte data []);
// package private (for hubs)
void updateChildren ()
throws SecurityException
{
byte data [] = new byte [128];
synchronized (lock) {
int status = getHubPorts (fd, data);
if (status < 0) {
children = null;
System.err.println ("bad hub port ioctl, errno " + -status);
return;
}
if (children == null || (data [0] & 0x7f) != children.length)
children = new DeviceImpl [data [0] & 0x7f];
for (int i = 0; i < children.length; i++) {
int devnum = 0x7f & data [1 + i];
DeviceImpl old = children [i];
if (Linux.debug && old != null
&& old.hub != null && old.hub != this)
System.err.println ("old.hub not this: " + old.hub);
if (devnum != 0) {
children [i] = (DeviceImpl) usb.getDevice (devnum);
if (children [i] != null && children [i].hub == null) {
children [i].hub = this;
children [i].hubPortNum = i + 1;
if (Linux.trace)
System.err.println ("usb-" + usb.getBusId ()
+ " hub dev" + getAddress ()
+ " port " + children [i].hubPortNum
+ " = dev" + children [i].getAddress ());
}
if (Linux.debug && children [i] != null
&& children [i].hub != this)
System.err.println ("new.hub not this: "
+ children [i].hub);
} else
children [i] = null;
}
}
}
private static native String getClaimer (int fd, int ifno);
/**
* Returns a system-specific string providing information
* about the driver claiming this interface, or null.
*/
public String getClaimer (int ifno)
{
return getClaimer (fd, ifno);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -