Skip to content

Instantly share code, notes, and snippets.

@alekseichuk
Created October 7, 2019 21:41
Show Gist options
  • Save alekseichuk/0988fc8b45d42ab52b9bc8e215a9360c to your computer and use it in GitHub Desktop.
Save alekseichuk/0988fc8b45d42ab52b9bc8e215a9360c to your computer and use it in GitHub Desktop.
usb4java
import java.util.List;
import javax.usb.UsbConfiguration;
import javax.usb.UsbConst;
import javax.usb.UsbControlIrp;
import javax.usb.UsbDevice;
import javax.usb.UsbDeviceDescriptor;
import javax.usb.UsbEndpoint;
import javax.usb.UsbException;
import javax.usb.UsbHostManager;
import javax.usb.UsbHub;
import javax.usb.UsbInterface;
public class FindUsbDevice2 {
private static UsbDevice mUsbDevice;
private static UsbEndpoint mInEndpoint = null;
private static UsbEndpoint mOutEndpoint = null;
public static void main(String[] args) throws UsbException {
UsbHub rootUsbHub = UsbHostManager.getUsbServices().getRootUsbHub();
for (DevInfo pl2303Dev : pl2303Devs) {
UsbDevice d = findDevice(rootUsbHub, pl2303Dev.vendorId, pl2303Dev.productId);
if (d != null) {
mUsbDevice = d;
System.out.println("Found!");
doTheStuff();
return;
}
}
System.out.println("Not Found.");
}
private static void doTheStuff() throws UsbException {
UsbConfiguration configuration = mUsbDevice.getActiveUsbConfiguration();
UsbInterface usbInterface = configuration.getUsbInterface((byte) 0);
try {
/* * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Crashes here with javax.usb.UsbClaimException: No interface is claimed */
usbInterface.claim(i -> true);
/* * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * */
for (Object endpointObj : usbInterface.getUsbEndpoints()) {
UsbEndpoint endpoint = (UsbEndpoint) endpointObj;
if (endpoint.getType() == UsbConst.ENDPOINT_TYPE_BULK
&& endpoint.getDirection() == UsbConst.ENDPOINT_DIRECTION_IN) {
mInEndpoint = endpoint;
} else if (endpoint.getType() == UsbConst.ENDPOINT_TYPE_BULK
&& endpoint.getDirection() == UsbConst.ENDPOINT_DIRECTION_OUT) {
mOutEndpoint = endpoint;
}
}
defaultSetup();
setBaudRate(9600);
setDataBits();
setParity();
requestInfo();
} finally {
usbInterface.release();
}
}
private static void requestInfo() {
// TODO
}
private static boolean defaultSetup() throws UsbException {
//Default Setup
byte[] buf = new byte[1];
//Specific vendor stuff that I barely understand but It is on linux drivers, So I trust :)
if (setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0404, 0, null) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8383, 0, buf) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0404, 1, null) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8383, 0, buf) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0000, 1, null) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0001, 0, null) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0002, 0x0044, null) < 0)
return false;
// End of specific vendor stuff
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_CONTROL_REQUEST, 0x0003, 0, null) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_LINE_CODING, 0x0000, 0, defaultSetLine) < 0)
return false;
if (setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0505, 0x1311, null) < 0)
return false;
return true;
}
private static int setControlCommand(int reqType , int request, int value, int index, byte[] data) throws UsbException {
UsbControlIrp irp = mUsbDevice.createUsbControlIrp(
(byte) reqType,
(byte) request,
(short) value,
(short) index
);
irp.setData(data);
mUsbDevice.syncSubmit(irp);
return irp.getData()[0];
}
public static UsbDevice findDevice(UsbHub hub, int vendorId, int productId) {
for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices()) {
UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device;
if (device.isUsbHub()) {
device = findDevice((UsbHub) device, vendorId, productId);
if (device != null) return device;
}
}
return null;
}
public static void setBaudRate(int baudRate) throws UsbException {
byte[] tempBuffer = new byte[4];
tempBuffer[0] = (byte) (baudRate & 0xff);
tempBuffer[1] = (byte) (baudRate >> 8 & 0xff);
tempBuffer[2] = (byte) (baudRate >> 16 & 0xff);
tempBuffer[3] = (byte) (baudRate >> 24 & 0xff);
if(tempBuffer[0] != defaultSetLine[0] || tempBuffer[1] != defaultSetLine[1] || tempBuffer[2] != defaultSetLine[2]
|| tempBuffer[3] != defaultSetLine[3])
{
defaultSetLine[0] = tempBuffer[0];
defaultSetLine[1] = tempBuffer[1];
defaultSetLine[2] = tempBuffer[2];
defaultSetLine[3] = tempBuffer[3];
setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_LINE_CODING, 0x0000, 0, defaultSetLine);
}
}
public static void setDataBits() throws UsbException {
if(defaultSetLine[6] != 0x08)
{
defaultSetLine[6] = 0x08;
setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_LINE_CODING, 0x0000, 0, defaultSetLine);
}
}
public static void setParity() throws UsbException {
if (defaultSetLine[5] != 0x00) {
defaultSetLine[5] = 0x00;
setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_LINE_CODING, 0x0000, 0, defaultSetLine);
}
}
private static class DevInfo {
final int vendorId;
final int productId;
DevInfo(int vendorId, int productId) {
this.vendorId = vendorId;
this.productId = productId;
}
@Override
public String toString() {
return "DevInfo{" +
"vendorId=" + Integer.toHexString(vendorId) +
", productId=" + Integer.toHexString(productId) +
'}';
}
}
// All the stuff below copied from
// https://github.com/felHR85/UsbSerial/blob/master/usbserial/src/main/java/com/felhr/usbserial/PL2303SerialDevice.java
private static final int PL2303_REQTYPE_HOST2DEVICE_VENDOR = 0x40;
private static final int PL2303_REQTYPE_DEVICE2HOST_VENDOR = 0xC0;
private static final int PL2303_REQTYPE_HOST2DEVICE = 0x21;
private static final int PL2303_VENDOR_WRITE_REQUEST = 0x01;
private static final int PL2303_SET_LINE_CODING = 0x20;
private static final int PL2303_SET_CONTROL_REQUEST = 0x22;
private static byte[] defaultSetLine = new byte[]{
(byte) 0x80, // [0:3] Baud rate (reverse hex encoding 9600:00 00 25 80 -> 80 25 00 00)
(byte) 0x25,
(byte) 0x00,
(byte) 0x00,
(byte) 0x00, // [4] Stop Bits (0=1, 1=1.5, 2=2)
(byte) 0x00, // [5] Parity (0=NONE 1=ODD 2=EVEN 3=MARK 4=SPACE)
(byte) 0x08 // [6] Data Bits (5=5, 6=6, 7=7, 8=8)
};
private static final DevInfo[] pl2303Devs = new DevInfo[]{
new DevInfo(0x04a5, 0x4027),
new DevInfo(0x067b, 0x2303),
new DevInfo(0x067b, 0x04bb),
new DevInfo(0x067b, 0x1234),
new DevInfo(0x067b, 0xaaa0),
new DevInfo(0x067b, 0xaaa2),
new DevInfo(0x067b, 0x0611),
new DevInfo(0x067b, 0x0612),
new DevInfo(0x067b, 0x0609),
new DevInfo(0x067b, 0x331a),
new DevInfo(0x067b, 0x0307),
new DevInfo(0x067b, 0x0463),
new DevInfo(0x0557, 0x2008),
new DevInfo(0x0547, 0x2008),
new DevInfo(0x04bb, 0x0a03),
new DevInfo(0x04bb, 0x0a0e),
new DevInfo(0x056e, 0x5003),
new DevInfo(0x056e, 0x5004),
new DevInfo(0x0eba, 0x1080),
new DevInfo(0x0eba, 0x2080),
new DevInfo(0x0df7, 0x0620),
new DevInfo(0x0584, 0xb000),
new DevInfo(0x2478, 0x2008),
new DevInfo(0x1453, 0x4026),
new DevInfo(0x0731, 0x0528),
new DevInfo(0x6189, 0x2068),
new DevInfo(0x11f7, 0x02df),
new DevInfo(0x04e8, 0x8001),
new DevInfo(0x11f5, 0x0001),
new DevInfo(0x11f5, 0x0003),
new DevInfo(0x11f5, 0x0004),
new DevInfo(0x11f5, 0x0005),
new DevInfo(0x0745, 0x0001),
new DevInfo(0x078b, 0x1234),
new DevInfo(0x10b5, 0xac70),
new DevInfo(0x079b, 0x0027),
new DevInfo(0x0413, 0x2101),
new DevInfo(0x0e55, 0x110b),
new DevInfo(0x0731, 0x2003),
new DevInfo(0x050d, 0x0257),
new DevInfo(0x058f, 0x9720),
new DevInfo(0x11f6, 0x2001),
new DevInfo(0x07aa, 0x002a),
new DevInfo(0x05ad, 0x0fba),
new DevInfo(0x5372, 0x2303),
new DevInfo(0x03f0, 0x0b39),
new DevInfo(0x03f0, 0x3139),
new DevInfo(0x03f0, 0x3239),
new DevInfo(0x03f0, 0x3524),
new DevInfo(0x04b8, 0x0521),
new DevInfo(0x04b8, 0x0522),
new DevInfo(0x054c, 0x0437),
new DevInfo(0x11ad, 0x0001),
new DevInfo(0x0b63, 0x6530),
new DevInfo(0x0b8c, 0x2303),
new DevInfo(0x110a, 0x1150)
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment