Ich möchte PaSoRi anders als Windows verwenden! Wenn ich darüber nachdenke, denke ich, dass Pythons nfcpy die erste Wahl ist, aber ich möchte es mit Java anstelle von Python machen! Zu diesem Zeitpunkt konnte ich den Beispielcode (oder fast alle Python-Beispiele ... !!) nicht finden, daher möchte ich den Prozess bis zu dem Punkt zusammenfassen, an dem er funktioniert.
Als erste Referenz habe ich stark auf den folgenden Artikel verwiesen. Ich bin den Vorfahren dankbar, die es implementiert haben, weil ich die Spezifikationen usw. nur erhalten kann, wenn ich es als Unternehmen kaufe.
Die folgenden Projekte scheinen neu und erfolgreich zu sein, daher werde ich sie übernehmen, ohne an irgendetwas zu denken. http://usb4java.org/
Auf der Website scheint es Low-Level-API (libusb) und High-Level-API (javax.usb) zu geben, und diesmal ist es einfacher zu verstehen, also habe ich versucht, javax.usb zu verwenden. In diesem Fall ist die folgende Seite sehr hilfreich.
Das normale Verfahren für den Zugriff auf ein USB-Gerät über die JSR-80-API lautet wie folgt:
Basierend auf dem obigen Artikel eine kurze Zusammenfassung des Kommunikationsverfahrens
Wie oben erwähnt, ist das Verfahren nicht so schwierig, solange Sie den Steuerbefehl für das Gerät kennen.
Da USB in einem Baumformat mit einem Hub verbunden werden kann, muss nach USB im Imozuru-Stil gesucht und der gewünschte USB gefunden werden. Sie können die virtuelle Route unten erhalten.
RCS380.java
UsbServices services = UsbHostManager.getUsbServices();
UsbHub rootHub = services.getRootUsbHub();
Suchen Sie dann nach dem Gerät anhand der Hersteller- und Produkt-ID, die Sie zuvor gesucht haben. Dies ist das Beispiel. Suchen Sie rekursiv, auch wenn ein Hub unterwegs ist.
RC380.java
public UsbDevice findDevice(UsbHub hub, int vendorId, int productId) throws UsbException, UnsupportedEncodingException {
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;
}
Geräteerkennung ist einfach!
Ich wollte sagen ..., aber es gibt einen Punkt, von dem ich persönlich süchtig war, und wenn ich so weitermache, ist die Konfiguration nicht aktiv, sodass ich in eine Situation geriet, in der UsbPipe für den Austausch an Endpunkt 2 nicht geöffnet werden konnte. Es war. Ich habe geprüft, ob es eine Methode zum Festlegen der Konfiguration oder zum Aktivieren der Konfiguration mit Javax gibt, konnte sie jedoch nicht finden. Daher werde ich die Konfiguration für die Konfiguration mit der Low Level API (libusb) nur an einer Stelle hier festlegen.
//javax.usb.*Wenn dies nur der Fall ist, ist die Konfiguration nicht aktiv. Aktivieren Sie daher die Konfiguration mit LibUSB ...
DeviceHandle dh = LibUsb.openDeviceWithVidPid(null, (short) RCS380.VENDOR_ID, (short) RCS380.PRODUCT_ID);
LibUsb.setAutoDetachKernelDriver(dh, true);
LibUsb.setConfiguration(dh, 1);
Von hier aus können Sie im Imozuru-Stil sofort zu UsbPipe gelangen.
RCS380.java
rcs380 = this.findDevice(rootHub, RCS380.VENDOR_ID, RCS380.PRODUCT_ID);
UsbConfiguration configuration = (UsbConfiguration) rcs380.getUsbConfigurations().get(0);
this.iface = (UsbInterface) configuration.getUsbInterfaces().get(0);
UsbEndpoint endpointOut = null, endpointIn = null;
for (int i = 0; i < iface.getUsbEndpoints().size(); i++) {
byte endpointAddr = (byte) ((UsbEndpoint) (iface.getUsbEndpoints().get(i))).getUsbEndpointDescriptor().bEndpointAddress();
if (((endpointAddr & 0x80) == 0x80)) {
endpointIn = (UsbEndpoint) (iface.getUsbEndpoints().get(i));
} else if ((endpointAddr & 0x80) == 0x00) {
endpointOut = (UsbEndpoint) (iface.getUsbEndpoints().get(i))
;
}
}
this.pipeOut = endpointOut.getUsbPipe();
this.pipeIn = endpointIn.getUsbPipe();
Der Punkt hier ist, dass es eine Regel zu geben scheint, dass die ersten 4 Bits der EndPoint-Adresse in Richtung von USB zum Host (IN) 0x8 sind. Wenn Sie also AND bei 0x80 nehmen und es bleibt, ist es für IN, andernfalls für OUT.
Für die detaillierten Befehle und die Datenstruktur des RC-S380 kann ich schnell auf die eingangs erwähnte Referenz verweisen, daher werde ich sie hier weglassen. Von hier zum Gerät
Und werfen Sie den Befehl weiter und werfen Sie den Befehl schließlich zum Abrufen.
buf = rcs380.sendCommand(Chipset.CMD_GET_FIRMWARE_VERSION);
System.out.println("Firmware version: " + String.format("%d.%02d", buf.get(1), buf.get(0)));
buf = rcs380.sendCommand(Chipset.CMD_GET_PD_DATA_VERSION);
System.out.println("PD Data version: " + String.format("%d.%02d", buf.get(1), buf.get(0)));
rcs380.sendCommand(Chipset.CMD_SWITCH_RF, new byte[]{0x00});
//0x01010f01 : F
//0x02030f03 : A
//0x03070f07 : B
rcs380.sendCommand(Chipset.CMD_IN_SET_RF, new byte[]{0x01, 0x01, 0x0f, 0x01});
rcs380.sendCommand(Chipset.CMD_IN_SET_PROTOCOL, new byte[]{0x00, 0x18, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x08, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0e, 0x04, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x06});
rcs380.sendCommand(Chipset.CMD_IN_SET_PROTOCOL, new byte[]{0x00, 0x18});
Auch hier denke ich, dass es am besten ist, die Artikel und Implementierungen der Vorfahren für die Code- und Datenstruktur des Befehls zu sehen ...!
Unten ist der Teil, der Felica liest.
System.out.println("********** Start **********");
boolean isLoop = true;
while (isLoop) {
buf = rcs380.sendCommand(Chipset.CMD_IN_COMM_RF, new byte[]{0x6e, 0x00, 0x06, 0x00, (byte) 0xff, (byte) 0xff, 0x01, 0x00});
if (Arrays.equals(buf.array(), new byte[]{(byte) 0x80, 0x00, 0x00, 0x00})) {
} else {
//Type-F
if (buf.get(5) == 0x14 && buf.get(6) == 0x01) {
System.out.println("IDm: " + Hex.encodeHexString(Arrays.copyOfRange(buf.array(), 7, 15)));
System.out.println("PMm: " + Hex.encodeHexString(Arrays.copyOfRange(buf.array(), 15, 23)));
isLoop = false;
}
}
Thread.sleep(250);
}
Wenn Sie fertig sind, schließen Sie die Rohre und so weiter.
rcs380.close();
Unten sind die Ausführungsergebnisse.
/Library/Java/JavaVirtualMachi ... ...
SONY RC-S380/P
Firmware version: 1.17
PD Data version: 1.00
********** Start **********
IDm: 01120312eb18f200
PMm: 100b4b428485d0ff
Process finished with exit code 0
Es ist schmutziger Code zu Testzwecken, aber es ist unten. https://github.com/nearprosmith/java-rcs380-test
Bitte zögern Sie nicht, auf Fehler oder Irrtümer hinzuweisen.
Recommended Posts