Lesen Sie Felica mit RC-S380 (PaSoRi) in Java

Überblick

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.

Referenz

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.

Eine kurze Zusammenfassung des Umgangs mit USB von Java aus

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:

  1. Holen Sie sich die entsprechenden UsbServices von UsbHostManager und Bootstrap.
  2. Greifen Sie mit Usb Services auf den Root-Hub zu. Der Root-Hub wird in der Anwendung als UsbHub betrachtet.
  3. Rufen Sie eine Liste der mit dem Root-Hub verbundenen UsbDevices ab. Untersuchen Sie alle Hubs der unteren Ebene, um das richtige UsbDevice zu finden.
  4. Verwenden Sie die Steuernachricht (UsbControlIrp), um direkt mit dem UsbDevice zu kommunizieren, oder fordern Sie das UsbInterface in der entsprechenden UsbConfiguration auf dem UsbDevice an und führen Sie die E / A mit dem auf dem UsbInterface verfügbaren UsbEndpoint aus.
  5. Wenn UsbEndpoint zum Ausführen von E / A verwendet wird, öffnen Sie die zugehörige UsbPipe. Upstream-Daten (USB-Gerät zum Host-Computer) und Downstream-Daten (Host-Computer zum USB-Gerät) werden von UsbPipe synchron oder asynchron gesendet.
  6. Schließen Sie UsbPipe und geben Sie das entsprechende UsbInterface frei, wenn die Anwendung keinen Zugriff mehr auf das UsbDevice benötigt.

Basierend auf dem obigen Artikel eine kurze Zusammenfassung des Kommunikationsverfahrens

  1. Erkennen Sie USB anhand der Hersteller-ID und der Produkt-ID. Jede ID wird eindeutig veröffentlicht (sollte). Für diesen RC-S380 lautet beispielsweise Hersteller-ID 0x054C, Produkt-ID 0x06C3. ..
  2. Rufen Sie von dort Konfiguration, Schnittstelle, Endpunkt ab. Darüber hinaus gibt es zwei Stellen, an denen Endpoint bei der Kommunikation mit USB tatsächlich Daten austauscht, sowohl nach innen als auch nach außen in Bezug auf USB.
  3. Senden Sie eine beliebige Kommunikation an das Gerät und erhalten Sie eine Antwort

Wie oben erwähnt, ist das Verfahren nicht so schwierig, solange Sie den Steuerbefehl für das Gerät kennen.

Trainieren

Geräteerkennung

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);

Holen Sie sich sofort zu UsbPipe

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.

Senden Sie Daten an UsbPipe und kommunizieren Sie

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

  1. ACK (keine Rückgabedaten)
  2. Set Command Type
  3. Get Firmware version
  4. Get PD DATA version
  5. Switch RF
  6. In Set RF
  7. In Set Protocol

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

Diese Quelle

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

Lesen Sie Felica mit RC-S380 (PaSoRi) in Java
Lesen Sie JSON in Java
Lesen Sie Binärdateien in Java 1
Lesen Sie Binärdateien in Java 2
Lesen Sie die Java-Eigenschaftendatei in C #
Verschlüsselung mit RSA-Verschlüsselung in Java
Lesen Sie CSV in Java (Super CSV Annotation)
HTTPS-Verbindung mit tls1.2 in Java 6
Ich habe versucht, JWT in Java zu verwenden
Ich habe versucht, die Elasticsearch-API in Java zu verwenden
Versuchen Sie es mit der Stream-API in Java
Map ohne Verwendung eines Arrays in Java
ERRORCODE = -4471 tritt in einer Java-Anwendung auf, die Db2 verwendet.
Versuchen Sie es mit der JSON-Format-API in Java
Lesen Sie die xlsx-Datei in Java mit Selenium
Lesen Sie eine Zeichenfolge in einer PDF-Datei mit Java
ChatWork4j für die Verwendung der ChatWork-API in Java
Partisierung in Java
[Java] API-Erstellung mit Jerjey (Jax-rs) mit Eclipse
Senden Sie E-Mails mit Amazon SES SMTP in Java
Senden Sie Push-Benachrichtigungen über Notification Hubs in Java
Änderungen in Java 11
Versuchen Sie es mit Sourcetrail (Win-Version) mit Java-Code
Janken in Java
Versuchen Sie es mit Sourcetrail (MacOS-Version) mit Java-Code
Passen Sie IP-Adressen mithilfe regulärer Ausdrücke in Java an
Hinzufügen, Lesen und Löschen von Excel-Kommentaren mit Java
[Java] Dateien in src / main / resources lesen
Zeigen Sie "Hello World" im Browser mit Java an
Zeigen Sie "Hello World" im Browser mit Java an
Umfangsrate in Java
Versuchen Sie es mit der Syntaxanalyse der COTOHA-API in Java
NLP4J Morphologische Analyse in Java (unter Verwendung von Kuromoji)
FizzBuzz in Java
Konvertieren Sie JSON und YAML in Java (mit Jackson und SnakeYAML)
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
Ich habe versucht, die erweiterte for-Anweisung in Java zu verwenden
Versuchen Sie es mit globalem Hooking in Java mithilfe der JNativeHook-Bibliothek
Unterschiede im Code bei Verwendung des Längensystems in Java
Sortieren mit Java-Komparator
Interpreter-Implementierung durch Java
Janken App in Java
Einschränkungsprogrammierung in Java
Setzen Sie Java8 in Centos7
NVL-artiger Typ in Java
Verbinden Sie Arrays in Java
"Hallo Welt" in Java
Java-Eigenschaftendatei lesen
Aufrufbare Schnittstelle in Java
Kommentare in der Java-Quelle
Formatieren Sie XML in Java
Einfache HTML-Spezialchars in Java
Schrottpraxis mit Java ②
Boyer-Moore-Implementierung in Java
Lesen Sie die Java HashMap-Quelle
Hallo Welt in Java
Verwenden Sie OpenCV mit Java
WebApi-Memorandum mit Java