Open icemagno opened 1 month ago
Eu implementei uma classe para disparar eventos quando meu Token é conectado / desconectado da porta USB usando a biblioteca JavaDoesUSB ( https://github.com/manuelbl/JavaDoesUSB ). Funcionou para mim e eu tentei deixar de uma forma mais genérica possível, mas obviamente serão necessários mais testes.
Essa biblioteca EXIGE Java >= 21
Segue a classe que eu desenvolvi:
package br.com.j1scorpii.usbdevice;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import net.codecrete.usb.Usb;
import net.codecrete.usb.UsbAlternateInterface;
import net.codecrete.usb.UsbDevice;
import net.codecrete.usb.UsbInterface;
public class DeviceManager {
private IDeviceEventObserver observer;
private boolean devicePresent = false;
private Map<Integer,JSONObject> devices = new HashMap<Integer,JSONObject>();
public static enum DeviceEventType{
CONNECTED,
DISCONNECTED
}
public boolean isDevicePresent() {
return devicePresent;
}
public DeviceManager( IDeviceEventObserver observer ) {
this.observer = observer;
}
public void monitorAll() {
monitorClass( -1 );
}
public void monitorClass( int classCode ) {
try {
for ( var device : Usb.getDevices() ) checkDevice(device, DeviceEventType.CONNECTED, classCode );
Usb.setOnDeviceConnected( device -> {
checkDevice( device, DeviceEventType.CONNECTED, classCode );
});
Usb.setOnDeviceDisconnected( device -> {
checkDevice( device, DeviceEventType.DISCONNECTED, classCode );
});
} catch( IllegalStateException t ) {
// PLEASE BE QUIET !!
}
}
private void checkDevice(UsbDevice device, DeviceEventType event, int classCodeFilter ) {
int vendorId = device.getVendorId(); // 1059H / 4185D Giesecke & Devrient GmbH
int productId = device.getProductId(); // 000bH / 23D StarSign Bio Token 3.0
String manufacturer = device.getManufacturer(); // Giesecke & Devrient GmbH
String product = "";
try { product = device.getProduct().toUpperCase().trim().replaceAll(" ", "_"); } catch ( Exception e ) {}
UsbInterface intf = device.getInterface(0);
UsbAlternateInterface alt = intf.getCurrentAlternate();
int classCode = alt.getClassCode();
// 4185 23 11 Giesecke & Devrient GmbH STARSIGN_CUT
// System.out.println( vendorId + " " + productId + " " + classCode + " " + manufacturer + " " + product );
// describe( device );
JSONObject deviceJson = new JSONObject()
.put("vendorId",vendorId)
.put("productId",productId)
.put("classCode",classCode)
.put("manufacturer",manufacturer)
.put("product",product);
if ( event == DeviceEventType.CONNECTED ) this.devices.put(classCode, deviceJson);
if ( event == DeviceEventType.DISCONNECTED ) this.devices.remove(classCode, deviceJson);
if ( classCodeFilter == -1 ) observer.notifyEvent( event, deviceJson );
else
if ( classCode == classCodeFilter ) { // 11 = Chip/SmartCard
this.devicePresent = ( event == DeviceEventType.CONNECTED );
observer.notifyEvent( event, deviceJson );
}
}
public Map<Integer, JSONObject> getDevices() {
return devices;
}
}
Para usar:
Implemente sua classe como a interface IDeviceEventObserver
public interface IDeviceEventObserver {
void notifyEvent( DeviceEventType eventType, JSONObject deviceJson );
}
Chame o monitor de dispositivos:
DeviceManager deviceManager = new DeviceManager( this );
deviceManager.monitorAll();
ou
deviceManager.monitor( classe ); // Onde 11 = "Chip/SmartCard"
Resultado ( monitora a classe 11 de Token/Smartcard ):
Evt: CONNECTED Presente?: true
{
"classCode": 11,
"product": "",
"productId": 23,
"vendorId": 4185,
"manufacturer": "Giesecke & Devrient GmbH"
}
Evt: DISCONNECTED Presente?: false
{
"classCode": 11,
"product": "",
"productId": 23,
"vendorId": 4185,
"manufacturer": "Giesecke & Devrient GmbH"
}
Monitora tudo:
Evt: CONNECTED
{
"classCode": 3,
"product": "DELL_MS116_USB_OPTICAL_MOUSE",
"productId": 12314,
"vendorId": 16700,
"manufacturer": "PixArt"
}
Evt: CONNECTED
{
"classCode": 3,
"product": "DELL_KB216_WIRED_KEYBOARD",
"productId": 8467,
"vendorId": 16700,
"manufacturer": "Љ"
}
Evt: CONNECTED
{
"classCode": 1,
"product": "LOGI_USB_HEADSET",
"productId": 2661,
"vendorId": 1133,
"manufacturer": "Logitech"
}
Algumas vezes, é útil saber simplesmente se algum token foi inserido ou removido da USB. Seria bom ter um listener para disparar eventos de inserção / remoção do token.
Eu tentei ler um keystore, mas ele pede senha quando tento fazer isso.