2019-10-27 00:02:40 +03:00
|
|
|
package nsusbloader.COM.USB;
|
2019-09-25 05:43:47 +03:00
|
|
|
|
|
|
|
import nsusbloader.ModelControllers.LogPrinter;
|
|
|
|
import nsusbloader.NSLDataTypes.EMsgType;
|
|
|
|
import org.usb4java.*;
|
|
|
|
|
2020-02-10 02:19:39 +03:00
|
|
|
public class UsbConnect {
|
2020-02-10 02:52:59 +03:00
|
|
|
private int DEFAULT_INTERFACE = 0;
|
2019-09-25 05:43:47 +03:00
|
|
|
|
|
|
|
private Context contextNS;
|
|
|
|
private DeviceHandle handlerNS;
|
2020-02-10 02:19:39 +03:00
|
|
|
private Device deviceNS;
|
2019-09-25 05:43:47 +03:00
|
|
|
|
|
|
|
private LogPrinter logPrinter;
|
|
|
|
|
2020-02-10 02:19:39 +03:00
|
|
|
private boolean connected; // TODO: replace to 'connectionFailure' and invert requests everywhere
|
|
|
|
|
|
|
|
public UsbConnect(LogPrinter logPrinter, boolean initForRCM){
|
2019-09-25 05:43:47 +03:00
|
|
|
this.logPrinter = logPrinter;
|
|
|
|
this.connected = false;
|
|
|
|
|
2020-02-10 02:19:39 +03:00
|
|
|
short VENDOR_ID;
|
|
|
|
short PRODUCT_ID;
|
|
|
|
|
|
|
|
if (initForRCM){
|
|
|
|
// CORRECT NV:
|
|
|
|
VENDOR_ID = 0x0955;
|
|
|
|
PRODUCT_ID = 0x7321;
|
|
|
|
/* // QA:
|
|
|
|
VENDOR_ID = 0x1a86;
|
|
|
|
PRODUCT_ID = 0x7523;
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
VENDOR_ID = 0x057E;
|
|
|
|
PRODUCT_ID = 0x3000;
|
|
|
|
}
|
|
|
|
|
2019-09-25 05:43:47 +03:00
|
|
|
int result;
|
|
|
|
|
|
|
|
// Creating Context required by libusb. Optional. TODO: Consider removing.
|
|
|
|
contextNS = new Context();
|
|
|
|
result = LibUsb.init(contextNS);
|
|
|
|
if (result != LibUsb.SUCCESS) {
|
|
|
|
logPrinter.print("libusb initialization\n Returned: "+result, EMsgType.FAIL);
|
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-10 02:19:39 +03:00
|
|
|
logPrinter.print("libusb initialization", EMsgType.PASS);
|
2019-09-25 05:43:47 +03:00
|
|
|
|
|
|
|
// Searching for NS in devices: obtain list of all devices
|
|
|
|
DeviceList deviceList = new DeviceList();
|
|
|
|
result = LibUsb.getDeviceList(contextNS, deviceList);
|
|
|
|
if (result < 0) {
|
|
|
|
logPrinter.print("Get device list\n Returned: "+result, EMsgType.FAIL);
|
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-10 02:19:39 +03:00
|
|
|
logPrinter.print("Get device list", EMsgType.PASS);
|
2019-09-25 05:43:47 +03:00
|
|
|
// Searching for NS in devices: looking for NS
|
|
|
|
DeviceDescriptor descriptor;
|
2020-02-10 02:19:39 +03:00
|
|
|
deviceNS = null;
|
2019-09-25 05:43:47 +03:00
|
|
|
for (Device device: deviceList){
|
|
|
|
descriptor = new DeviceDescriptor(); // mmm.. leave it as is.
|
|
|
|
result = LibUsb.getDeviceDescriptor(device, descriptor);
|
|
|
|
if (result != LibUsb.SUCCESS){
|
|
|
|
logPrinter.print("Read file descriptors for USB devices\n Returned: "+result, EMsgType.FAIL);
|
|
|
|
LibUsb.freeDeviceList(deviceList, true);
|
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-10 02:19:39 +03:00
|
|
|
if ((descriptor.idVendor() == VENDOR_ID) && descriptor.idProduct() == PRODUCT_ID){
|
2019-09-25 05:43:47 +03:00
|
|
|
deviceNS = device;
|
|
|
|
logPrinter.print("Read file descriptors for USB devices", EMsgType.PASS);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Free device list.
|
2020-02-10 02:19:39 +03:00
|
|
|
if (deviceNS == null){
|
2019-09-25 05:43:47 +03:00
|
|
|
logPrinter.print("NS in connected USB devices not found", EMsgType.FAIL);
|
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-10 02:19:39 +03:00
|
|
|
logPrinter.print("NS in connected USB devices found", EMsgType.PASS);
|
|
|
|
|
2019-09-25 05:43:47 +03:00
|
|
|
// Handle NS device
|
|
|
|
handlerNS = new DeviceHandle();
|
|
|
|
result = LibUsb.open(deviceNS, handlerNS);
|
|
|
|
if (result != LibUsb.SUCCESS) {
|
|
|
|
logPrinter.print("Open NS USB device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
|
|
|
if (result == LibUsb.ERROR_ACCESS)
|
|
|
|
logPrinter.print("Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!\n\n" +
|
2020-02-10 02:19:39 +03:00
|
|
|
String.format("Steps to set 'udev' rules:\n" +
|
|
|
|
"root # vim /etc/udev/rules.d/99-NS.rules\n" +
|
|
|
|
"SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", GROUP=\"plugdev\"\n" +
|
|
|
|
"root # udevadm control --reload-rules && udevadm trigger\n", VENDOR_ID, PRODUCT_ID)
|
|
|
|
, EMsgType.INFO);
|
2019-09-25 05:43:47 +03:00
|
|
|
// Let's make a bit dirty workaround since such shit happened
|
|
|
|
logPrinter.print("Requested context close", EMsgType.INFO);
|
|
|
|
LibUsb.exit(contextNS);
|
|
|
|
return; // And close
|
|
|
|
}
|
|
|
|
else
|
|
|
|
logPrinter.print("Open NS USB device", EMsgType.PASS);
|
|
|
|
|
|
|
|
logPrinter.print("Free device list", EMsgType.INFO);
|
|
|
|
LibUsb.freeDeviceList(deviceList, true);
|
|
|
|
|
|
|
|
// DO some stuff to connected NS
|
2019-12-10 23:26:43 +03:00
|
|
|
// Actually, there are not drivers in Linux kernel that are using this device..
|
|
|
|
if (LibUsb.setAutoDetachKernelDriver(handlerNS, true) == LibUsb.SUCCESS)
|
|
|
|
logPrinter.print("Handle kernel driver attach & detach", EMsgType.PASS);
|
2019-09-25 05:43:47 +03:00
|
|
|
else
|
2019-12-10 23:26:43 +03:00
|
|
|
logPrinter.print("Skip kernel driver attach & detach", EMsgType.INFO);
|
2019-09-25 05:43:47 +03:00
|
|
|
/*
|
|
|
|
// Reset device
|
|
|
|
result = LibUsb.resetDevice(handlerNS);
|
|
|
|
if (result == 0)
|
|
|
|
logPrinter.print("Reset device", EMsgType.PASS);
|
|
|
|
else {
|
|
|
|
logPrinter.print("Reset device returned: " + result, EMsgType.FAIL);
|
|
|
|
updateAndClose();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*/
|
2020-02-10 02:19:39 +03:00
|
|
|
if ( ! initForRCM){
|
|
|
|
// Set configuration (soft reset if needed)
|
|
|
|
result = LibUsb.setConfiguration(handlerNS, 1); // 1 - configuration all we need
|
|
|
|
if (result != LibUsb.SUCCESS){
|
|
|
|
logPrinter.print("Set active configuration to device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2019-09-25 05:43:47 +03:00
|
|
|
logPrinter.print("Set active configuration to device.", EMsgType.PASS);
|
2020-02-10 02:19:39 +03:00
|
|
|
}
|
2019-09-25 05:43:47 +03:00
|
|
|
// Claim interface
|
|
|
|
result = LibUsb.claimInterface(handlerNS, DEFAULT_INTERFACE);
|
|
|
|
if (result != LibUsb.SUCCESS) {
|
2020-02-10 02:19:39 +03:00
|
|
|
logPrinter.print("Claim interface\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
2019-09-25 05:43:47 +03:00
|
|
|
close();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-10 02:19:39 +03:00
|
|
|
logPrinter.print("Claim interface", EMsgType.PASS);
|
2019-09-25 05:43:47 +03:00
|
|
|
|
|
|
|
this.connected = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get USB status
|
|
|
|
* @return status of connection
|
|
|
|
*/
|
2020-02-10 02:19:39 +03:00
|
|
|
public boolean isConnected() { return connected; }
|
2019-09-25 05:43:47 +03:00
|
|
|
/**
|
|
|
|
* Getter for handler
|
|
|
|
* @return DeviceHandle of NS
|
|
|
|
*/
|
2020-02-10 02:19:39 +03:00
|
|
|
public DeviceHandle getNsHandler(){ return handlerNS; }
|
|
|
|
/**
|
|
|
|
* Getter for 'Bus ID' where NS located found
|
|
|
|
*/
|
|
|
|
public int getNsBus(){
|
|
|
|
return LibUsb.getBusNumber(deviceNS);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Getter for 'Device address' where NS located at
|
|
|
|
*/
|
|
|
|
public int getNsAddress(){
|
|
|
|
return LibUsb.getDeviceAddress(deviceNS);
|
|
|
|
}
|
2019-09-25 05:43:47 +03:00
|
|
|
/**
|
|
|
|
* Correct exit
|
|
|
|
* */
|
2020-02-10 02:19:39 +03:00
|
|
|
public void close(){
|
2019-09-25 05:43:47 +03:00
|
|
|
// Close handler in the end
|
|
|
|
if (handlerNS != null) {
|
|
|
|
// Try to release interface
|
|
|
|
int result = LibUsb.releaseInterface(handlerNS, DEFAULT_INTERFACE);
|
|
|
|
|
|
|
|
if (result != LibUsb.SUCCESS)
|
2020-02-10 02:19:39 +03:00
|
|
|
logPrinter.print("Release interface" +
|
|
|
|
"\n Returned: "+result+" (sometimes it's not an issue)", EMsgType.WARNING);
|
2019-09-25 05:43:47 +03:00
|
|
|
else
|
|
|
|
logPrinter.print("Release interface", EMsgType.PASS);
|
|
|
|
|
|
|
|
LibUsb.close(handlerNS);
|
|
|
|
logPrinter.print("Requested handler close", EMsgType.INFO);
|
|
|
|
}
|
|
|
|
// Close context in the end
|
|
|
|
if (contextNS != null) {
|
|
|
|
LibUsb.exit(contextNS);
|
|
|
|
logPrinter.print("Requested context close", EMsgType.INFO);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|