Je veux utiliser PaSoRi autre que Windows! Quand j'y pense, je pense que le nfcpy de Python est le premier choix, mais je veux le faire avec Java au lieu de Python! À ce moment-là, je n'ai pas pu trouver l'exemple de code (ou presque tous les exemples Python ... !!), alors j'aimerais résumer le processus jusqu'au point où il fonctionne.
Comme référence tout d'abord, j'ai beaucoup fait référence à l'article suivant. Je suis reconnaissant aux ancêtres qui l'ont mis en œuvre car je ne peux pas obtenir les spécifications, etc. à moins que je ne l'achète en tant que société.
Les projets suivants semblent nouveaux et prospères, je les adopterai donc sans penser à rien. http://usb4java.org/
En regardant le site, il semble qu'il existe des API de bas niveau (libusb) et de haut niveau (javax.usb), et cette fois, ce sera plus facile à comprendre, alors j'ai essayé d'utiliser javax.usb. Dans ce cas, la page suivante sera très utile.
La procédure normale pour accéder à un périphérique USB à l'aide de l'API JSR-80 est la suivante:
Sur la base de l'article ci-dessus, un bref résumé de la procédure de communication
Comme mentionné ci-dessus, ce n'est pas une procédure si difficile tant que vous connaissez la commande de contrôle de l'appareil.
Étant donné que l'USB peut être connecté dans un format arborescent avec un hub, il est nécessaire de rechercher l'USB dans un style Imozuru et de trouver l'USB souhaité. Vous pouvez obtenir l'itinéraire virtuel ci-dessous.
RCS380.java
UsbServices services = UsbHostManager.getUsbServices();
UsbHub rootHub = services.getRootUsbHub();
Recherchez ensuite l'appareil par le fournisseur et l'ID de produit que vous avez recherchés précédemment. Voici l'exemple. Recherche récursive même s'il y a un hub au milieu.
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;
}
La détection des appareils est facile!
Je voulais dire ..., mais il y a un point auquel j'étais accro personnellement ici, et si je continue comme ça, la configuration n'est pas active, donc je suis tombé dans une situation où UsbPipe pour échanger à Endpoint 2 ne pouvait pas être ouvert. C'était. J'ai vérifié s'il existe une méthode pour setConfiguration ou activateConfiguration avec javax, mais je ne l'ai pas trouvée, donc pour plus tard, je définirai la configuration à l'aide de l'API de bas niveau (libusb) uniquement à un endroit ici.
//javax.usb.*Si c'est juste, la configuration n'est pas active, alors activez la configuration avec LibUSB ...
DeviceHandle dh = LibUsb.openDeviceWithVidPid(null, (short) RCS380.VENDOR_ID, (short) RCS380.PRODUCT_ID);
LibUsb.setAutoDetachKernelDriver(dh, true);
LibUsb.setConfiguration(dh, 1);
De là, vous pouvez accéder à UsbPipe immédiatement dans le style Imozuru.
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();
Le point ici est qu'il semble y avoir une règle selon laquelle les 4 premiers bits de l'adresse EndPoint dans la direction USB vers l'hôte (IN) sont 0x8. Donc, si vous prenez AND à 0x80 et qu'il reste, c'est pour IN, sinon c'est pour OUT.
Pour les commandes détaillées et la structure de données du RC-S380, je pense qu'il est rapide de se référer à la référence mentionnée au début, donc je vais l'omettre ici. De là à l'appareil
Et continuez à lancer la commande, et enfin lancez la commande en interrogation.
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});
Encore une fois, je pense qu'il est préférable de voir les articles et implémentations des ancêtres pour le code et la structure de données de la commande ...!
Ci-dessous, la partie qui lit Felica.
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);
}
Lorsque vous avez terminé, fermez les tuyaux et ainsi de suite.
rcs380.close();
Voici les résultats de l'exécution.
/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
C'est du code sale à des fins de test, mais il est ci-dessous. https://github.com/nearprosmith/java-rcs380-test
N'hésitez pas à signaler toute erreur ou erreur.
Recommended Posts