diff --git a/README.md b/README.md index eeddcb1..4c7d899 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,20 @@ JRE 8u60 or higher. See below. ### macOS -See 'Linux' section. +Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' section. Set 'Security & Privacy' settings if needed. +If you use different MacOS (not Mojave) - check release section for another JAR file. + ### Windows: * Download Zadig: https://zadig.akeo.ie/ -* Open tinfoil. Set 'Title Managment' -> 'Usb install NSP' +* Open tinfoil. Set 'Title Management' -> 'Usb install NSP' * Connect NS to PC -* Open Zadig, select NS in dropdown, select 'libusbK (v3.0.7.0)' (version may vary), click 'Install WCID Driver' +* Open Zadig +* Click 'Options' and select 'List All Devices' +* Select NS in dropdown, select 'libusbK (v3.0.7.0)' (version may vary), click 'Install WCID Driver' * Check that in device list of you system you have 'libusbK USB Devices' folder and your NS inside of it * Download and install Java JRE (8+) * Get this application (JAR file) double-click on on it (alternatively open 'cmd', go to place where jar located and execute via `java -jar thisAppName.jar`) @@ -66,10 +70,10 @@ Table 'Status' = 'Uploaded' does not means that file installed. It means that it Handling successful/failed installation is a purpose of the other side application (TinFoil/GoldLeaf). (And they don't provide any feedback interfaces so I can't detect success/failure.) ## TODO: -- [x] macOS QA v0.1 -- [ ] macOS QA v0.2 (partly) +- [x] macOS QA v0.1 (Mojave) +- [x] macOS QA v0.2.2 (Mojave) - [x] Windows support -- [ ] code refactoring (almost. todo: printLog() ) +- [x] code refactoring - [x] GoldLeaf support - [ ] XCI support - [ ] File order sort (non-critical) diff --git a/pom.xml b/pom.xml index 918b010..7e5c26a 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ NS-USBloader ns-usbloader - 0.2.3_DEV-SNAPSHOT + 0.3_DEV-SNAPSHOT https://github.com/developersu/ns-usbloader/ @@ -140,7 +140,7 @@ org.usb4java usb4java - 1.2.0 + 1.3.0 compile diff --git a/src/main/java/nsusbloader/Controllers/NSLMainController.java b/src/main/java/nsusbloader/Controllers/NSLMainController.java index 3befcbd..04c1522 100644 --- a/src/main/java/nsusbloader/Controllers/NSLMainController.java +++ b/src/main/java/nsusbloader/Controllers/NSLMainController.java @@ -11,7 +11,7 @@ import javafx.stage.FileChooser; import nsusbloader.AppPreferences; import nsusbloader.MediatorControl; import nsusbloader.NSLMain; -import nsusbloader.UsbCommunications; +import nsusbloader.USB.UsbCommunications; import java.io.File; import java.net.URL; @@ -137,7 +137,7 @@ public class NSLMainController implements Initializable { if (usbThread == null || !usbThread.isAlive()){ List nspToUpload; if ((nspToUpload = tableFilesListController.getFiles()) == null) { - resourceBundle.getString("logsNoFolderFileSelected"); + logArea.setText(resourceBundle.getString("logsNoFolderFileSelected")); return; }else { logArea.setText(resourceBundle.getString("logsFilesToUploadTitle")+"\n"); diff --git a/src/main/java/nsusbloader/MediatorControl.java b/src/main/java/nsusbloader/MediatorControl.java index 5544864..e828571 100644 --- a/src/main/java/nsusbloader/MediatorControl.java +++ b/src/main/java/nsusbloader/MediatorControl.java @@ -18,7 +18,7 @@ public class MediatorControl { public void setController(NSLMainController controller){ this.applicationController = controller; } - NSLMainController getContoller(){ return this.applicationController; } + public NSLMainController getContoller(){ return this.applicationController; } public synchronized void setTransferActive(boolean state) { isTransferActive.set(state); diff --git a/src/main/java/nsusbloader/NSLMain.java b/src/main/java/nsusbloader/NSLMain.java index 7fd6cba..ca8f8f3 100644 --- a/src/main/java/nsusbloader/NSLMain.java +++ b/src/main/java/nsusbloader/NSLMain.java @@ -12,17 +12,16 @@ import java.util.Locale; import java.util.ResourceBundle; public class NSLMain extends Application { - public static final String appVersion = "v0.2.3_DEV"; + public static final String appVersion = "v0.3_DEV"; @Override public void start(Stage primaryStage) throws Exception{ FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml")); ResourceBundle rb; - if (Locale.getDefault().getISO3Language().equals("rus")) - rb = ResourceBundle.getBundle("locale", new Locale("ru")); - else - rb = ResourceBundle.getBundle("locale", new Locale("en")); + Locale userLocale = new Locale(Locale.getDefault().getISO3Language()); // NOTE: user locale based on ISO3 Language codes + rb = ResourceBundle.getBundle("locale", userLocale); + loader.setResources(rb); Parent root = loader.load(); diff --git a/src/main/java/nsusbloader/USB/LogPrinter.java b/src/main/java/nsusbloader/USB/LogPrinter.java new file mode 100644 index 0000000..6faed8a --- /dev/null +++ b/src/main/java/nsusbloader/USB/LogPrinter.java @@ -0,0 +1,63 @@ +package nsusbloader.USB; + +import nsusbloader.NSLDataTypes.EFileStatus; +import nsusbloader.NSLDataTypes.EMsgType; + +import java.io.File; +import java.util.HashMap; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class LogPrinter { + private MessagesConsumer msgConsumer; + private BlockingQueue msgQueue; + private BlockingQueue progressQueue; + private HashMap statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap + + LogPrinter(){ + this.msgQueue = new LinkedBlockingQueue<>(); + this.progressQueue = new LinkedBlockingQueue<>(); + this.statusMap = new HashMap<>(); + this.msgConsumer = new MessagesConsumer(this.msgQueue, this.progressQueue, this.statusMap); + this.msgConsumer.start(); + } + /** + * This is what will print to textArea of the application. + * */ + public void print(String message, EMsgType type){ + try { + switch (type){ + case PASS: + msgQueue.put("[ PASS ] "+message+"\n"); + break; + case FAIL: + msgQueue.put("[ FAIL ] "+message+"\n"); + break; + case INFO: + msgQueue.put("[ INFO ] "+message+"\n"); + break; + case WARNING: + msgQueue.put("[ WARN ] "+message+"\n"); + break; + default: + msgQueue.put(message); + } + }catch (InterruptedException ie){ + ie.printStackTrace(); + } + } + /** + * Update progress for progress bar + * */ + public void updateProgress(Double value) throws InterruptedException{ + progressQueue.put(value); + } + /** + * When we're done + * */ + public void updateAndClose(HashMap nspMap, EFileStatus status){ + for (String fileName: nspMap.keySet()) + statusMap.put(fileName, status); + msgConsumer.interrupt(); + } +} diff --git a/src/main/java/nsusbloader/MessagesConsumer.java b/src/main/java/nsusbloader/USB/MessagesConsumer.java similarity index 96% rename from src/main/java/nsusbloader/MessagesConsumer.java rename to src/main/java/nsusbloader/USB/MessagesConsumer.java index 303580a..d8bd818 100644 --- a/src/main/java/nsusbloader/MessagesConsumer.java +++ b/src/main/java/nsusbloader/USB/MessagesConsumer.java @@ -1,10 +1,11 @@ -package nsusbloader; +package nsusbloader.USB; import javafx.animation.AnimationTimer; import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressIndicator; import javafx.scene.control.TextArea; import nsusbloader.Controllers.NSTableViewController; +import nsusbloader.MediatorControl; import nsusbloader.NSLDataTypes.EFileStatus; import java.util.ArrayList; @@ -69,7 +70,7 @@ public class MessagesConsumer extends AnimationTimer { } } - void interrupt(){ + public void interrupt(){ this.isInterrupted = true; } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/PFS/NCAFile.java b/src/main/java/nsusbloader/USB/PFS/NCAFile.java similarity index 97% rename from src/main/java/nsusbloader/PFS/NCAFile.java rename to src/main/java/nsusbloader/USB/PFS/NCAFile.java index ea537ce..9b52e12 100644 --- a/src/main/java/nsusbloader/PFS/NCAFile.java +++ b/src/main/java/nsusbloader/USB/PFS/NCAFile.java @@ -1,4 +1,4 @@ -package nsusbloader.PFS; +package nsusbloader.USB.PFS; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/src/main/java/nsusbloader/PFS/PFSProvider.java b/src/main/java/nsusbloader/USB/PFS/PFSProvider.java similarity index 70% rename from src/main/java/nsusbloader/PFS/PFSProvider.java rename to src/main/java/nsusbloader/USB/PFS/PFSProvider.java index 6888b80..bd627cc 100644 --- a/src/main/java/nsusbloader/PFS/PFSProvider.java +++ b/src/main/java/nsusbloader/USB/PFS/PFSProvider.java @@ -1,5 +1,6 @@ -package nsusbloader.PFS; +package nsusbloader.USB.PFS; +import nsusbloader.USB.LogPrinter; import nsusbloader.NSLDataTypes.EMsgType; import nsusbloader.ServiceWindow; @@ -8,15 +9,14 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.*; -import java.util.concurrent.BlockingQueue; /** * Used in GoldLeaf USB protocol * */ public class PFSProvider { private static final byte[] PFS0 = new byte[]{(byte)0x50, (byte)0x46, (byte)0x53, (byte)0x30}; // PFS0, and what did you think? - - private BlockingQueue msgQueue; + + private LogPrinter logPrinter; private ResourceBundle rb; private RandomAccessFile randAccessFile; @@ -25,20 +25,18 @@ public class PFSProvider { private long bodySize; private int ticketID = -1; - public PFSProvider(File nspFile, BlockingQueue msgQueue){ - this.msgQueue = msgQueue; + public PFSProvider(File nspFile, LogPrinter logPrinter){ + this.logPrinter = logPrinter; try { this.randAccessFile = new RandomAccessFile(nspFile, "r"); nspFileName = nspFile.getName(); } catch (FileNotFoundException fnfe){ - printLog("PFS File not founnd: \n "+fnfe.getMessage(), EMsgType.FAIL); + logPrinter.print("PFS File not founnd: \n "+fnfe.getMessage(), EMsgType.FAIL); nspFileName = null; } - if (Locale.getDefault().getISO3Language().equals("rus")) - rb = ResourceBundle.getBundle("locale", new Locale("ru")); - else - rb = ResourceBundle.getBundle("locale", new Locale("en")); + Locale userLocale = new Locale(Locale.getDefault().getISO3Language()); + rb = ResourceBundle.getBundle("locale", userLocale); } public boolean init() { @@ -48,22 +46,22 @@ public class PFSProvider { int filesCount; int header; - printLog("PFS Start NSP file analyze for ["+nspFileName+"]", EMsgType.INFO); + logPrinter.print("PFS Start NSP file analyze for ["+nspFileName+"]", EMsgType.INFO); try { byte[] fileStartingBytes = new byte[12]; // Read PFS0, files count, header, padding (4 zero bytes) if (randAccessFile.read(fileStartingBytes) == 12) - printLog("PFS Read file starting bytes.", EMsgType.PASS); + logPrinter.print("PFS Read file starting bytes.", EMsgType.PASS); else { - printLog("PFS Read file starting bytes.", EMsgType.FAIL); + logPrinter.print("PFS Read file starting bytes.", EMsgType.FAIL); randAccessFile.close(); return false; } // Check PFS0 if (Arrays.equals(PFS0, Arrays.copyOfRange(fileStartingBytes, 0, 4))) - printLog("PFS Read 'PFS0'.", EMsgType.PASS); + logPrinter.print("PFS Read 'PFS0'.", EMsgType.PASS); else { - printLog("PFS Read 'PFS0'.", EMsgType.WARNING); + logPrinter.print("PFS Read 'PFS0'.", EMsgType.WARNING); if (!ServiceWindow.getConfirmationWindow(nspFileName+"\n"+rb.getString("windowTitleConfirmWrongPFS0"), rb.getString("windowBodyConfirmWrongPFS0"))) { randAccessFile.close(); return false; @@ -72,19 +70,19 @@ public class PFSProvider { // Get files count filesCount = ByteBuffer.wrap(Arrays.copyOfRange(fileStartingBytes, 4, 8)).order(ByteOrder.LITTLE_ENDIAN).getInt(); if (filesCount > 0 ) { - printLog("PFS Read files count [" + filesCount + "]", EMsgType.PASS); + logPrinter.print("PFS Read files count [" + filesCount + "]", EMsgType.PASS); } else { - printLog("PFS Read files count", EMsgType.FAIL); + logPrinter.print("PFS Read files count", EMsgType.FAIL); randAccessFile.close(); return false; } // Get header header = ByteBuffer.wrap(Arrays.copyOfRange(fileStartingBytes, 8, 12)).order(ByteOrder.LITTLE_ENDIAN).getInt(); if (header > 0 ) - printLog("PFS Read header ["+header+"]", EMsgType.PASS); + logPrinter.print("PFS Read header ["+header+"]", EMsgType.PASS); else { - printLog("PFS Read header ", EMsgType.FAIL); + logPrinter.print("PFS Read header ", EMsgType.FAIL); randAccessFile.close(); return false; } @@ -103,10 +101,10 @@ public class PFSProvider { for (int i=0; i= 0?EMsgType.PASS:EMsgType.WARNING); - printLog(" NCA size check: "+nca_size, nca_size >= 0?EMsgType.PASS: EMsgType.WARNING); - printLog(" NCA name offset check: "+nca_name_offset, nca_name_offset >= 0?EMsgType.PASS:EMsgType.WARNING); + logPrinter.print(" Padding check", offset == 0?EMsgType.PASS:EMsgType.WARNING); + logPrinter.print(" NCA offset check: "+nca_offset, nca_offset >= 0?EMsgType.PASS:EMsgType.WARNING); + logPrinter.print(" NCA size check: "+nca_size, nca_size >= 0?EMsgType.PASS: EMsgType.WARNING); + logPrinter.print(" NCA name offset check: "+nca_name_offset, nca_name_offset >= 0?EMsgType.PASS:EMsgType.WARNING); NCAFile ncaFile = new NCAFile(); ncaFile.setNcaOffset(nca_offset); @@ -130,15 +128,15 @@ public class PFSProvider { // Final offset byte[] bufForInt = new byte[4]; if ((randAccessFile.read(bufForInt) == 4) && (Arrays.equals(bufForInt, new byte[4]))) - printLog("PFS Final padding check", EMsgType.PASS); + logPrinter.print("PFS Final padding check", EMsgType.PASS); else - printLog("PFS Final padding check", EMsgType.WARNING); + logPrinter.print("PFS Final padding check", EMsgType.WARNING); // Calculate position including header for body size offset bodySize = randAccessFile.getFilePointer()+header; //********************************************************************************************* // Collect file names from NCAs - printLog("PFS Collecting file names", EMsgType.INFO); + logPrinter.print("PFS Collecting file names", EMsgType.INFO); List ncaFN; // Temporary byte[] b = new byte[1]; // Temporary for (int i=0; i { private final int DEFAULT_INTERFACE = 0; - private BlockingQueue msgQueue; - private BlockingQueue progressQueue; - private HashMap statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap + private LogPrinter logPrinter; private EFileStatus status = EFileStatus.FAILED; - private MessagesConsumer msgConsumer; - private HashMap nspMap; private Context contextNS; @@ -52,39 +44,35 @@ public class UsbCommunications extends Task { this.nspMap = new HashMap<>(); for (File f: nspList) nspMap.put(f.getName(), f); - this.msgQueue = new LinkedBlockingQueue<>(); - this.progressQueue = new LinkedBlockingQueue<>(); - this.statusMap = new HashMap<>(); - this.msgConsumer = new MessagesConsumer(this.msgQueue, this.progressQueue, this.statusMap); + this.logPrinter = new LogPrinter(); } @Override protected Void call() { - this.msgConsumer.start(); int result = -9999; - printLog("\tStart chain", EMsgType.INFO); + logPrinter.print("\tStart chain", EMsgType.INFO); // Creating Context required by libusb. Optional. TODO: Consider removing. contextNS = new Context(); result = LibUsb.init(contextNS); if (result != LibUsb.SUCCESS) { - printLog("libusb initialization\n Returned: "+result, EMsgType.FAIL); + logPrinter.print("libusb initialization\n Returned: "+result, EMsgType.FAIL); close(); return null; } else - printLog("libusb initialization", EMsgType.PASS); + logPrinter.print("libusb initialization", EMsgType.PASS); // Searching for NS in devices: obtain list of all devices DeviceList deviceList = new DeviceList(); result = LibUsb.getDeviceList(contextNS, deviceList); if (result < 0) { - printLog("Get device list\n Returned: "+result, EMsgType.FAIL); + logPrinter.print("Get device list\n Returned: "+result, EMsgType.FAIL); close(); return null; } else { - printLog("Get device list", EMsgType.PASS); + logPrinter.print("Get device list", EMsgType.PASS); } // Searching for NS in devices: looking for NS DeviceDescriptor descriptor; @@ -93,14 +81,14 @@ public class UsbCommunications extends Task { descriptor = new DeviceDescriptor(); // mmm.. leave it as is. result = LibUsb.getDeviceDescriptor(device, descriptor); if (result != LibUsb.SUCCESS){ - printLog("Read file descriptors for USB devices\n Returned: "+result, EMsgType.FAIL); + logPrinter.print("Read file descriptors for USB devices\n Returned: "+result, EMsgType.FAIL); LibUsb.freeDeviceList(deviceList, true); close(); return null; } if ((descriptor.idVendor() == 0x057E) && descriptor.idProduct() == 0x3000){ deviceNS = device; - printLog("Read file descriptors for USB devices", EMsgType.PASS); + logPrinter.print("Read file descriptors for USB devices", EMsgType.PASS); break; } } @@ -114,13 +102,13 @@ public class UsbCommunications extends Task { switch (result){ case 0: - printLog("DBG: getActiveConfigDescriptor\n"+configDescriptor.dump(), EMsgType.PASS); + logPrinter.print("DBG: getActiveConfigDescriptor\n"+configDescriptor.dump(), EMsgType.PASS); break; case LibUsb.ERROR_NOT_FOUND: - printLog("DBG: getActiveConfigDescriptor: ERROR_NOT_FOUND", EMsgType.FAIL); + logPrinter.print("DBG: getActiveConfigDescriptor: ERROR_NOT_FOUND", EMsgType.FAIL); break; default: - printLog("DBG: getActiveConfigDescriptor: "+result, EMsgType.FAIL); + logPrinter.print("DBG: getActiveConfigDescriptor: "+result, EMsgType.FAIL); break; } @@ -141,10 +129,10 @@ public class UsbCommunications extends Task { ////////////////////////////////////////// DEBUG INFORMATION END ///////////////////////////////////////////// if (deviceNS != null){ - printLog("NS in connected USB devices found", EMsgType.PASS); + logPrinter.print("NS in connected USB devices found", EMsgType.PASS); } else { - printLog("NS in connected USB devices not found", EMsgType.FAIL); + logPrinter.print("NS in connected USB devices not found", EMsgType.FAIL); close(); return null; } @@ -152,27 +140,16 @@ public class UsbCommunications extends Task { handlerNS = new DeviceHandle(); result = LibUsb.open(deviceNS, handlerNS); if (result != LibUsb.SUCCESS) { - switch (result){ - case LibUsb.ERROR_ACCESS: - printLog("Open NS USB device\n Returned: ERROR_ACCESS", EMsgType.FAIL); - printLog("Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!", EMsgType.INFO); - break; - case LibUsb.ERROR_NO_MEM: - printLog("Open NS USB device\n Returned: ERROR_NO_MEM", EMsgType.FAIL); - break; - case LibUsb.ERROR_NO_DEVICE: - printLog("Open NS USB device\n Returned: ERROR_NO_DEVICE", EMsgType.FAIL); - break; - default: - printLog("Open NS USB device\n Returned:" + result, EMsgType.FAIL); - } + 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)!", EMsgType.INFO); close(); return null; } else - printLog("Open NS USB device", EMsgType.PASS); + logPrinter.print("Open NS USB device", EMsgType.PASS); - printLog("Free device list", EMsgType.INFO); + logPrinter.print("Free device list", EMsgType.INFO); LibUsb.freeDeviceList(deviceList, true); // DO some stuff to connected NS @@ -180,99 +157,55 @@ public class UsbCommunications extends Task { boolean canDetach = LibUsb.hasCapability(LibUsb.CAP_SUPPORTS_DETACH_KERNEL_DRIVER); // if cant, it's windows ot old lib if (canDetach){ int usedByKernel = LibUsb.kernelDriverActive(handlerNS, DEFAULT_INTERFACE); - if (usedByKernel == LibUsb.SUCCESS){ - printLog("Can proceed with libusb driver", EMsgType.PASS); // we're good - } - else { - switch (usedByKernel){ - case 1: // used by kernel - result = LibUsb.detachKernelDriver(handlerNS, DEFAULT_INTERFACE); - printLog("Detach kernel required", EMsgType.INFO); - if (result != 0) { - switch (result){ - case LibUsb.ERROR_NOT_FOUND: - printLog("Detach kernel\n Returned: ERROR_NOT_FOUND", EMsgType.FAIL); - break; - case LibUsb.ERROR_INVALID_PARAM: - printLog("Detach kernel\n Returned: ERROR_INVALID_PARAM", EMsgType.FAIL); - break; - case LibUsb.ERROR_NO_DEVICE: - printLog("Detach kernel\n Returned: ERROR_NO_DEVICE", EMsgType.FAIL); - break; - case LibUsb.ERROR_NOT_SUPPORTED: // Should never appear only if libusb buggy - printLog("Detach kernel\n Returned: ERROR_NOT_SUPPORTED", EMsgType.FAIL); - break; - default: - printLog("Detach kernel\n Returned: " + result, EMsgType.FAIL); - break; - } - close(); - return null; - } - else { - printLog("Detach kernel", EMsgType.PASS); - break; - } - case LibUsb.ERROR_NO_DEVICE: - printLog("Can't proceed with libusb driver\n Returned: ERROR_NO_DEVICE", EMsgType.FAIL); - break; - case LibUsb.ERROR_NOT_SUPPORTED: - printLog("Can't proceed with libusb driver\n Returned: ERROR_NOT_SUPPORTED", EMsgType.FAIL); - break; - default: - printLog("Can't proceed with libusb driver\n Returned: "+result, EMsgType.FAIL); - } - } + if (usedByKernel == LibUsb.SUCCESS){ + logPrinter.print("Can proceed with libusb driver", EMsgType.PASS); // we're good + } + else if (usedByKernel == 1) { // used by kernel + result = LibUsb.detachKernelDriver(handlerNS, DEFAULT_INTERFACE); + logPrinter.print("Detach kernel required", EMsgType.INFO); + if (result != 0) { + logPrinter.print("Detach kernel\n Returned: " + UsbErrorCodes.getErrCode(result), EMsgType.FAIL); + close(); + return null; + } else + logPrinter.print("Detach kernel", EMsgType.PASS); + } + else + logPrinter.print("Can't proceed with libusb driver\n Returned: "+UsbErrorCodes.getErrCode(usedByKernel), EMsgType.FAIL); } else - printLog("libusb doesn't supports function 'CAP_SUPPORTS_DETACH_KERNEL_DRIVER'. Proceeding.", EMsgType.WARNING); + logPrinter.print("libusb doesn't support function 'CAP_SUPPORTS_DETACH_KERNEL_DRIVER'. It's normal. Proceeding.", EMsgType.WARNING); /* // Reset device result = LibUsb.resetDevice(handlerNS); if (result == 0) - printLog("Reset device", EMsgType.PASS); + logPrinter.print("Reset device", EMsgType.PASS); else { - printLog("Reset device returned: " + result, EMsgType.FAIL); - close(); + logPrinter.print("Reset device returned: " + result, EMsgType.FAIL); + updateAndClose(); return null; } */ // Set configuration (soft reset if needed) result = LibUsb.setConfiguration(handlerNS, 1); // 1 - configuration all we need if (result != LibUsb.SUCCESS){ - switch (result){ - case LibUsb.ERROR_NOT_FOUND: - printLog("Set active configuration to device\n Returned: ERROR_NOT_FOUND", EMsgType.FAIL); - break; - case LibUsb.ERROR_BUSY: - printLog("Set active configuration to device\n Returned: ERROR_BUSY", EMsgType.FAIL); - break; - case LibUsb.ERROR_NO_DEVICE: - printLog("Set active configuration to device\n Returned: ERROR_NO_DEVICE", EMsgType.FAIL); - break; - case LibUsb.ERROR_INVALID_PARAM: - printLog("Set active configuration to device\n Returned: ERROR_INVALID_PARAM", EMsgType.FAIL); - break; - default: - printLog("Set active configuration to device\n Returned: "+result, EMsgType.FAIL); - break; - } + logPrinter.print("Set active configuration to device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); close(); return null; } else { - printLog("Set active configuration to device.", EMsgType.PASS); + logPrinter.print("Set active configuration to device.", EMsgType.PASS); } // Claim interface result = LibUsb.claimInterface(handlerNS, DEFAULT_INTERFACE); if (result != LibUsb.SUCCESS) { - printLog("Claim interface\n Returned: "+result, EMsgType.FAIL); + logPrinter.print("Claim interface\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); close(); return null; } else - printLog("Claim interface", EMsgType.PASS); + logPrinter.print("Claim interface", EMsgType.PASS); //-------------------------------------------------------------------------------------------------------------- if (protocol.equals("TinFoil")) { @@ -282,7 +215,7 @@ public class UsbCommunications extends Task { } close(); - printLog("\tEnd chain", EMsgType.INFO); + logPrinter.print("\tEnd chain", EMsgType.INFO); return null; } /** @@ -304,11 +237,11 @@ public class UsbCommunications extends Task { // Send list of NSP files: // Proceed "TUL0" if (!writeToUsb("TUL0".getBytes(StandardCharsets.US_ASCII))) { // new byte[]{(byte) 0x54, (byte) 0x55, (byte) 0x76, (byte) 0x30} - printLog("TF Send list of files: handshake", EMsgType.FAIL); + logPrinter.print("TF Send list of files: handshake", EMsgType.FAIL); return false; } else - printLog("TF Send list of files: handshake", EMsgType.PASS); + logPrinter.print("TF Send list of files: handshake", EMsgType.PASS); //Collect file names StringBuilder nspListNamesBuilder = new StringBuilder(); // Add every title to one stringBuilder for(String nspFileName: nspMap.keySet()) { @@ -323,24 +256,24 @@ public class UsbCommunications extends Task { //byteBuffer.reset(); // Sending NSP list - printLog("TF Send list of files", EMsgType.INFO); + logPrinter.print("TF Send list of files", EMsgType.INFO); if (!writeToUsb(nspListSize)) { // size of the list we're going to transfer goes... - printLog(" [send list length]", EMsgType.FAIL); + logPrinter.print(" [send list length]", EMsgType.FAIL); return false; } - printLog(" [send list length]", EMsgType.PASS); + logPrinter.print(" [send list length]", EMsgType.PASS); if (!writeToUsb(new byte[8])) { // 8 zero bytes goes... - printLog(" [send padding]", EMsgType.FAIL); + logPrinter.print(" [send padding]", EMsgType.FAIL); return false; } - printLog(" [send padding]", EMsgType.PASS); + logPrinter.print(" [send padding]", EMsgType.PASS); if (!writeToUsb(nspListNames)) { // list of the names goes... - printLog(" [send list itself]", EMsgType.FAIL); + logPrinter.print(" [send list itself]", EMsgType.FAIL); return false; } - printLog(" [send list itself]", EMsgType.PASS); + logPrinter.print(" [send list itself]", EMsgType.PASS); return true; } @@ -348,7 +281,7 @@ public class UsbCommunications extends Task { * After we sent commands to NS, this chain starts * */ private boolean proceedCommands(){ - printLog("TF Awaiting for NS commands.", EMsgType.INFO); + logPrinter.print("TF Awaiting for NS commands.", EMsgType.INFO); /* byte[] magic = new byte[4]; ByteBuffer bb = StandardCharsets.UTF_8.encode("TUC0").rewind().get(magic); @@ -370,11 +303,11 @@ public class UsbCommunications extends Task { // 8th to 12th(explicits) bytes in returned data stands for command ID as unsigned integer (Little-endian). Actually, we have to compare arrays here, but in real world it can't be greater then 0/1/2, thus: // BTW also protocol specifies 4th byte to be 0x00 kinda indicating that that this command is valid. But, as you may see, never happens other situation when it's not = 0. if (receivedArray[8] == 0x00){ //0x00 - exit - printLog("TF Received EXIT command. Terminating.", EMsgType.PASS); + logPrinter.print("TF Received EXIT command. Terminating.", EMsgType.PASS); return true; // All interaction with USB device should be ended (expected); } else if ((receivedArray[8] == 0x01) || (receivedArray[8] == 0x02)){ //0x01 - file range; 0x02 unknown bug on backend side (dirty hack). - printLog("TF Received FILE_RANGE command. Proceeding: [0x0"+receivedArray[8]+"]", EMsgType.PASS); + logPrinter.print("TF Received FILE_RANGE command. Proceeding: [0x0"+receivedArray[8]+"]", EMsgType.PASS); /*// We can get in this pocket a length of file name (+32). Why +32? I dunno man.. Do we need this? Definitely not. This app can live without it. long receivedSize = ByteBuffer.wrap(Arrays.copyOfRange(receivedArray, 12,20)).order(ByteOrder.LITTLE_ENDIAN).getLong(); logsArea.appendText("[V] Received FILE_RANGE command. Size: "+Long.toUnsignedString(receivedSize)+"\n"); // this shit returns string that will be chosen next '+32'. And, BTW, can't be greater then 512 @@ -414,7 +347,7 @@ public class UsbCommunications extends Task { return false; String receivedRequestedNSP = new String(receivedArray, StandardCharsets.UTF_8); - printLog("TF Reply to requested file: "+receivedRequestedNSP + logPrinter.print("TF Reply to requested file: "+receivedRequestedNSP +"\n Range Size: "+receivedRangeSize +"\n Range Offset: "+receivedRangeOffset, EMsgType.INFO); @@ -428,7 +361,7 @@ public class UsbCommunications extends Task { byte[] bufferCurrent ;//= new byte[1048576]; // eq. Allocate 1mb int bufferLength; if (bufferedInStream.skip(receivedRangeOffset) != receivedRangeOffset){ - printLog("TF Requested skip is out of file size. Nothing to transmit.", EMsgType.FAIL); + logPrinter.print("TF Requested skip is out of file size. Nothing to transmit.", EMsgType.FAIL); return false; } @@ -446,11 +379,11 @@ public class UsbCommunications extends Task { if (isProgessBarInitiated){ try { if (currentOffset+readPice == receivedRangeOffset){ - progressQueue.put(1.0); + logPrinter.updateProgress(1.0); isProgessBarInitiated = false; } else - progressQueue.put((currentOffset+readPice)/(receivedRangeSize/100.0) / 100.0); + logPrinter.updateProgress((currentOffset+readPice)/(receivedRangeSize/100.0) / 100.0); }catch (InterruptedException ie){ getException().printStackTrace(); // TODO: Do something with this } @@ -468,28 +401,28 @@ public class UsbCommunications extends Task { if (bufferLength != -1){ //write to USB if (!writeToUsb(bufferCurrent)) { - printLog("TF Failure during NSP transmission.", EMsgType.FAIL); + logPrinter.print("TF Failure during NSP transmission.", EMsgType.FAIL); return false; } currentOffset += readPice; } else { - printLog("TF Reading of stream suddenly ended.", EMsgType.WARNING); + logPrinter.print("TF Reading of stream suddenly ended.", EMsgType.WARNING); return false; } } bufferedInStream.close(); } catch (FileNotFoundException fnfe){ - printLog("TF FileNotFoundException:\n "+fnfe.getMessage(), EMsgType.FAIL); + logPrinter.print("TF FileNotFoundException:\n "+fnfe.getMessage(), EMsgType.FAIL); fnfe.printStackTrace(); return false; } catch (IOException ioe){ - printLog("TF IOException:\n "+ioe.getMessage(), EMsgType.FAIL); + logPrinter.print("TF IOException:\n "+ioe.getMessage(), EMsgType.FAIL); ioe.printStackTrace(); return false; } catch (ArithmeticException ae){ - printLog("TF ArithmeticException (can't cast end offset minus current to 'integer'):\n "+ae.getMessage(), EMsgType.FAIL); + logPrinter.print("TF ArithmeticException (can't cast end offset minus current to 'integer'):\n "+ae.getMessage(), EMsgType.FAIL); ae.printStackTrace(); return false; } @@ -502,26 +435,26 @@ public class UsbCommunications extends Task { * false if failed * */ private boolean sendResponse(byte[] rangeSize){ // This method as separate function itself for application needed as a cookie in the middle of desert. - printLog("TF Sending response", EMsgType.INFO); + logPrinter.print("TF Sending response", EMsgType.INFO); if (!writeToUsb(new byte[] { (byte) 0x54, (byte) 0x55, (byte) 0x43, (byte) 0x30, // 'TUC0' (byte) 0x01, // CMD_TYPE_RESPONSE = 1 (byte) 0x00, (byte) 0x00, (byte) 0x00, // kinda padding. Guys, didn't you want to use integer value for CMD semantic? (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00} ) // Send integer value of '1' in Little-endian format. ){ - printLog(" [1/3]", EMsgType.FAIL); + logPrinter.print(" [1/3]", EMsgType.FAIL); return false; } - printLog(" [1/3]", EMsgType.PASS); + logPrinter.print(" [1/3]", EMsgType.PASS); if(!writeToUsb(rangeSize)) { // Send EXACTLY what has been received - printLog(" [2/3]", EMsgType.FAIL); + logPrinter.print(" [2/3]", EMsgType.FAIL); return false; } - printLog(" [2/3]", EMsgType.PASS); + logPrinter.print(" [2/3]", EMsgType.PASS); if(!writeToUsb(new byte[12])) { // kinda another one padding - printLog(" [3/3]", EMsgType.FAIL); + logPrinter.print(" [3/3]", EMsgType.FAIL); return false; } - printLog(" [3/3]", EMsgType.PASS); + logPrinter.print(" [3/3]", EMsgType.PASS); return true; } @@ -542,14 +475,14 @@ public class UsbCommunications extends Task { private final byte[] CMD_Finish = new byte[]{0x47, 0x4c, 0x55, 0x43, 0x07, 0x00, 0x00, 0x00}; GoldLeaf(){ - printLog("===========================================================================", EMsgType.INFO); - PFSProvider pfsElement = new PFSProvider(nspMap.get(nspMap.keySet().toArray()[0]), msgQueue); + logPrinter.print("===========================================================================", EMsgType.INFO); + PFSProvider pfsElement = new PFSProvider(nspMap.get(nspMap.keySet().toArray()[0]), logPrinter); if (!pfsElement.init()) { - printLog("GL File provided have incorrect structure and won't be uploaded", EMsgType.FAIL); + logPrinter.print("GL File provided have incorrect structure and won't be uploaded", EMsgType.FAIL); status = EFileStatus.INCORRECT_FILE_FAILED; return; } - printLog("GL File structure validated and it will be uploaded", EMsgType.PASS); + logPrinter.print("GL File structure validated and it will be uploaded", EMsgType.PASS); if (initGoldLeafProtocol(pfsElement)) status = EFileStatus.UPLOADED; // else - no change status that is already set to FAILED @@ -560,9 +493,9 @@ public class UsbCommunications extends Task { // Go connect to GoldLeaf if (writeToUsb(CMD_ConnectionRequest)) - printLog("GL Initiating GoldLeaf connection", EMsgType.PASS); + logPrinter.print("GL Initiating GoldLeaf connection", EMsgType.PASS); else { - printLog("GL Initiating GoldLeaf connection", EMsgType.FAIL); + logPrinter.print("GL Initiating GoldLeaf connection", EMsgType.FAIL); return false; } while (true) { @@ -595,7 +528,7 @@ public class UsbCommunications extends Task { continue; } if (Arrays.equals(readByte, CMD_Finish)) { - printLog("GL Closing GoldLeaf connection: Transfer successful.", EMsgType.PASS); + logPrinter.print("GL Closing GoldLeaf connection: Transfer successful.", EMsgType.PASS); break; } } @@ -605,24 +538,24 @@ public class UsbCommunications extends Task { * ConnectionResponse command handler * */ private boolean handleConnectionResponse(PFSProvider pfsElement){ - printLog("GL 'ConnectionResonse' command:", EMsgType.INFO); + logPrinter.print("GL 'ConnectionResponse' command:", EMsgType.INFO); if (!writeToUsb(CMD_NSPName)) { - printLog(" [1/3]", EMsgType.FAIL); + logPrinter.print(" [1/3]", EMsgType.FAIL); return false; } - printLog(" [1/3]", EMsgType.PASS); + logPrinter.print(" [1/3]", EMsgType.PASS); if (!writeToUsb(pfsElement.getBytesNspFileNameLength())) { - printLog(" [2/3]", EMsgType.FAIL); + logPrinter.print(" [2/3]", EMsgType.FAIL); return false; } - printLog(" [2/3]", EMsgType.PASS); + logPrinter.print(" [2/3]", EMsgType.PASS); if (!writeToUsb(pfsElement.getBytesNspFileName())) { - printLog(" [3/3]", EMsgType.FAIL); + logPrinter.print(" [3/3]", EMsgType.FAIL); return false; } - printLog(" [3/3]", EMsgType.PASS); + logPrinter.print(" [3/3]", EMsgType.PASS); return true; } @@ -630,43 +563,43 @@ public class UsbCommunications extends Task { * Start command handler * */ private boolean handleStart(PFSProvider pfsElement){ - printLog("GL Handle 'Start' command:", EMsgType.INFO); + logPrinter.print("GL Handle 'Start' command:", EMsgType.INFO); if (!writeToUsb(CMD_NSPData)) { - printLog(" [Send command]", EMsgType.FAIL); + logPrinter.print(" [Send command]", EMsgType.FAIL); return false; } - printLog(" [Send command]", EMsgType.PASS); + logPrinter.print(" [Send command]", EMsgType.PASS); if (!writeToUsb(pfsElement.getBytesCountOfNca())) { - printLog(" [Send length]", EMsgType.FAIL); + logPrinter.print(" [Send length]", EMsgType.FAIL); return false; } - printLog(" [Send length]", EMsgType.PASS); + logPrinter.print(" [Send length]", EMsgType.PASS); int ncaCount = pfsElement.getIntCountOfNca(); - printLog(" [Send information for "+ncaCount+" files]", EMsgType.INFO); + logPrinter.print(" [Send information for "+ncaCount+" files]", EMsgType.INFO); for (int i = 0; i < ncaCount; i++){ if (!writeToUsb(pfsElement.getNca(i).getNcaFileNameLength())) { - printLog(" [1/4] File #"+i, EMsgType.FAIL); + logPrinter.print(" [1/4] File #"+i, EMsgType.FAIL); return false; } - printLog(" [1/4] File #"+i, EMsgType.PASS); + logPrinter.print(" [1/4] File #"+i, EMsgType.PASS); if (!writeToUsb(pfsElement.getNca(i).getNcaFileName())) { - printLog(" [2/4] File #"+i, EMsgType.FAIL); + logPrinter.print(" [2/4] File #"+i, EMsgType.FAIL); return false; } - printLog(" [2/4] File #"+i, EMsgType.PASS); + logPrinter.print(" [2/4] File #"+i, EMsgType.PASS); if (!writeToUsb(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(pfsElement.getBodySize()+pfsElement.getNca(i).getNcaOffset()).array())) { // offset. real. - printLog(" [2/4] File #"+i, EMsgType.FAIL); + logPrinter.print(" [2/4] File #"+i, EMsgType.FAIL); return false; } - printLog(" [3/4] File #"+i, EMsgType.PASS); + logPrinter.print(" [3/4] File #"+i, EMsgType.PASS); if (!writeToUsb(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(pfsElement.getNca(i).getNcaSize()).array())) { // size - printLog(" [4/4] File #"+i, EMsgType.FAIL); + logPrinter.print(" [4/4] File #"+i, EMsgType.FAIL); return false; } - printLog(" [4/4] File #"+i, EMsgType.PASS); + logPrinter.print(" [4/4] File #"+i, EMsgType.PASS); } return true; } @@ -679,18 +612,18 @@ public class UsbCommunications extends Task { int requestedNcaID; boolean isProgessBarInitiated = false; if (isItRawRequest) { - printLog("GL Handle 'Content' command", EMsgType.INFO); + logPrinter.print("GL Handle 'Content' command", EMsgType.INFO); byte[] readByte = readFromUsb(); if (readByte == null || readByte.length != 4) { - printLog(" [Read requested ID]", EMsgType.FAIL); + logPrinter.print(" [Read requested ID]", EMsgType.FAIL); return false; } requestedNcaID = ByteBuffer.wrap(readByte).order(ByteOrder.LITTLE_ENDIAN).getInt(); - printLog(" [Read requested ID = "+requestedNcaID+" ]", EMsgType.PASS); + logPrinter.print(" [Read requested ID = "+requestedNcaID+" ]", EMsgType.PASS); } else { requestedNcaID = pfsElement.getNcaTicketID(); - printLog("GL Handle 'Ticket' command (ID = "+requestedNcaID+" )", EMsgType.INFO); + logPrinter.print("GL Handle 'Ticket' command (ID = "+requestedNcaID+" )", EMsgType.INFO); } long realNcaOffset = pfsElement.getNca(requestedNcaID).getNcaOffset()+pfsElement.getBodySize(); @@ -723,11 +656,11 @@ public class UsbCommunications extends Task { if (isProgessBarInitiated){ try { if (readFrom+readPice == realNcaSize){ - progressQueue.put(1.0); + logPrinter.updateProgress(1.0); isProgessBarInitiated = false; } else - progressQueue.put((readFrom+readPice)/(realNcaSize/100.0) / 100.0); + logPrinter.updateProgress((readFrom+readPice)/(realNcaSize/100.0) / 100.0); }catch (InterruptedException ie){ getException().printStackTrace(); // TODO: Do something with this } @@ -742,7 +675,7 @@ public class UsbCommunications extends Task { bufferedInStream.close(); } catch (IOException ioe){ - printLog(" Failed to read NCA ID "+requestedNcaID+". IO Exception:\n "+ioe.getMessage(), EMsgType.FAIL); + logPrinter.print(" Failed to read NCA ID "+requestedNcaID+". IO Exception:\n "+ioe.getMessage(), EMsgType.FAIL); ioe.printStackTrace(); return false; } @@ -754,30 +687,27 @@ public class UsbCommunications extends Task { * Correct exit * */ private void close(){ - // close handler in the end + // Close handler in the end if (handlerNS != null) { // Try to release interface int result = LibUsb.releaseInterface(handlerNS, DEFAULT_INTERFACE); if (result != LibUsb.SUCCESS) - printLog("Release interface\n Returned: "+result+" (sometimes it's not an issue)", EMsgType.WARNING); + logPrinter.print("Release interface\n Returned: "+result+" (sometimes it's not an issue)", EMsgType.WARNING); else - printLog("Release interface", EMsgType.PASS); + logPrinter.print("Release interface", EMsgType.PASS); LibUsb.close(handlerNS); - printLog("Requested handler close", EMsgType.INFO); + logPrinter.print("Requested handler updateAndClose", EMsgType.INFO); } - // close context in the end + // Close context in the end if (contextNS != null) { LibUsb.exit(contextNS); - printLog("Requested context close", EMsgType.INFO); + logPrinter.print("Requested context updateAndClose", EMsgType.INFO); } - // Report status - for (String fileName: nspMap.keySet()) - statusMap.put(fileName, status); - - msgConsumer.interrupt(); + // Report status and close + logPrinter.updateAndClose(nspMap, status); } /** * Sending any byte array to USB device @@ -792,27 +722,12 @@ public class UsbCommunications extends Task { int result; result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 0); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01 if (result != LibUsb.SUCCESS){ - switch (result){ - case LibUsb.ERROR_TIMEOUT: - printLog("Data transfer (write) issue\n Returned: ERROR_TIMEOUT", EMsgType.FAIL); - break; - case LibUsb.ERROR_PIPE: //WUT?? I dunno man looks overkill in here.. - printLog("Data transfer (write) issue\n Returned: ERROR_PIPE", EMsgType.FAIL); - break; - case LibUsb.ERROR_OVERFLOW: - printLog("Data transfer (write) issue\n Returned: ERROR_OVERFLOW", EMsgType.FAIL); - break; - case LibUsb.ERROR_NO_DEVICE: - printLog("Data transfer (write) issue\n Returned: ERROR_NO_DEVICE", EMsgType.FAIL); - break; - default: - printLog("Data transfer (write) issue\n Returned: "+result, EMsgType.FAIL); - } - printLog("Execution stopped", EMsgType.FAIL); + logPrinter.print("Data transfer (write) issue\n Returned: "+ UsbErrorCodes.getErrCode(result), EMsgType.FAIL); + logPrinter.print("Execution stopped", EMsgType.FAIL); return false; }else { if (writeBufTransferred.get() != message.length){ - printLog("Data transfer (write) issue\n Requested: "+message.length+"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); + logPrinter.print("Data transfer (write) issue\n Requested: "+message.length+"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); return false; } else { @@ -834,26 +749,8 @@ public class UsbCommunications extends Task { result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 0); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81 if (result != LibUsb.SUCCESS){ - switch (result){ - case LibUsb.ERROR_TIMEOUT: - printLog("Data transfer (read) issue\n Returned: ERROR_TIMEOUT", EMsgType.FAIL); - break; - case LibUsb.ERROR_PIPE: //WUT?? I dunno man looks overkill in here.. - printLog("Data transfer (read) issue\n Returned: ERROR_PIPE", EMsgType.FAIL); - break; - case LibUsb.ERROR_OVERFLOW: - printLog("Data transfer (read) issue\n Returned: ERROR_OVERFLOW", EMsgType.FAIL); - break; - case LibUsb.ERROR_NO_DEVICE: - printLog("Data transfer (read) issue\n Returned: ERROR_NO_DEVICE", EMsgType.FAIL); - break; - case LibUsb.ERROR_IO: - printLog("Data transfer (read) issue\n Returned: ERROR_IO", EMsgType.FAIL); - break; - default: - printLog("Data transfer (read) issue\n Returned: "+result, EMsgType.FAIL); - } - printLog("Execution stopped", EMsgType.FAIL); + logPrinter.print("Data transfer (read) issue\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); + logPrinter.print("Execution stopped", EMsgType.FAIL); return null; } else { int trans = readBufTransferred.get(); @@ -865,30 +762,4 @@ public class UsbCommunications extends Task { return receivedBytes; } } - - /** - * This is what will print to textArea of the application. - * */ - private void printLog(String message, EMsgType type){ - try { - switch (type){ - case PASS: - msgQueue.put("[ PASS ] "+message+"\n"); - break; - case FAIL: - msgQueue.put("[ FAIL ] "+message+"\n"); - break; - case INFO: - msgQueue.put("[ INFO ] "+message+"\n"); - break; - case WARNING: - msgQueue.put("[ WARN ] "+message+"\n"); - break; - default: - msgQueue.put(message); - } - }catch (InterruptedException ie){ - ie.printStackTrace(); - } - } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/USB/UsbErrorCodes.java b/src/main/java/nsusbloader/USB/UsbErrorCodes.java new file mode 100644 index 0000000..3c7ffde --- /dev/null +++ b/src/main/java/nsusbloader/USB/UsbErrorCodes.java @@ -0,0 +1,38 @@ +package nsusbloader.USB; + +import org.usb4java.LibUsb; + +class UsbErrorCodes { + static String getErrCode(int value){ + switch (value){ + case LibUsb.ERROR_ACCESS: + return "ERROR_ACCESS"; + case LibUsb.ERROR_BUSY: + return "ERROR_BUSY"; + case LibUsb.ERROR_INTERRUPTED: + return "ERROR_INTERRUPTED"; + case LibUsb.ERROR_INVALID_PARAM: + return "ERROR_INVALID_PARAM"; + case LibUsb.ERROR_IO: + return "ERROR_IO"; + case LibUsb.ERROR_NO_DEVICE: + return "ERROR_NO_DEVICE"; + case LibUsb.ERROR_NO_MEM: + return "ERROR_NO_MEM"; + case LibUsb.ERROR_NOT_FOUND: + return "ERROR_NOT_FOUND"; + case LibUsb.ERROR_NOT_SUPPORTED: + return "ERROR_NOT_SUPPORTED"; + case LibUsb.ERROR_OTHER: + return "ERROR_OTHER"; + case LibUsb.ERROR_OVERFLOW: + return "ERROR_OVERFLOW"; + case LibUsb.ERROR_PIPE: + return "ERROR_PIPE"; + case LibUsb.ERROR_TIMEOUT: + return "ERROR_TIMEOUT"; + default: + return Integer.toString(value); + } + } +} diff --git a/src/main/resources/locale_en.properties b/src/main/resources/locale.properties similarity index 100% rename from src/main/resources/locale_en.properties rename to src/main/resources/locale.properties diff --git a/src/main/resources/locale_ru.properties b/src/main/resources/locale_rus.properties similarity index 87% rename from src/main/resources/locale_ru.properties rename to src/main/resources/locale_rus.properties index 1c4d268..2c7ed7e 100644 --- a/src/main/resources/locale_ru.properties +++ b/src/main/resources/locale_rus.properties @@ -5,7 +5,7 @@ logsEnteredAsMsg2=\u0427\u0442\u043E\u0431\u044B \u0438\u0437\u0431\u0435\u0436\ logsFilesToUploadTitle=\u0424\u0430\u0439\u043B\u044B \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438: logsGreetingsMessage=\u0414\u043E\u0431\u0440\u043E \u043F\u043E\u0436\u0430\u043B\u043E\u0432\u0430\u0442\u044C \u0432 NS-USBloader logsNoFolderFileSelected=\u0424\u0430\u0439\u043B\u044B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u044B - \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E. -windowBodyConfirmExit=\u0421\u0435\u0439\u0447\u0430\u0441 \u043F\u0440\u043E\u0438\u0441\u0445\u043E\u0434\u0438\u0442 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043D\u043D\u044B\u0445 \u0438 \u0437\u0430\u043A\u0440\u044B\u0442\u0438\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043F\u0440\u0435\u0440\u0432\u0451\u0442 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0443.\n\u042D\u0442\u043E \u0445\u0443\u0434\u0448\u0435\u0435 \u0447\u0442\u043E \u0442\u044B \u043C\u043E\u0436\u0435\u0448\u044C \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0434\u0435\u043B\u0430\u0442\u044C.\n\u041F\u0440\u0435\u0440\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u0438 \u0432\u044B\u0439\u0442\u0438? +windowBodyConfirmExit=\u0421\u0435\u0439\u0447\u0430\u0441 \u043F\u0440\u043E\u0438\u0441\u0445\u043E\u0434\u0438\u0442 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043D\u043D\u044B\u0445 \u0438 \u0437\u0430\u043A\u0440\u044B\u0442\u0438\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043F\u0440\u0435\u0440\u0432\u0451\u0442 \u0435\u0451.\n\u042D\u0442\u043E \u0445\u0443\u0434\u0448\u0435\u0435 \u0447\u0442\u043E \u0442\u044B \u043C\u043E\u0436\u0435\u0448\u044C \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0434\u0435\u043B\u0430\u0442\u044C.\n\u041F\u0440\u0435\u0440\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u0438 \u0432\u044B\u0439\u0442\u0438? windowTitleConfirmExit=\u041D\u0435\u0442, \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0441\u044C! btnStop=\u041F\u0440\u0435\u0440\u0432\u0430\u0442\u044C logsGreetingsMessage2=--\n\ diff --git a/src/main/resources/locale_ukr.properties b/src/main/resources/locale_ukr.properties new file mode 100644 index 0000000..9f59484 --- /dev/null +++ b/src/main/resources/locale_ukr.properties @@ -0,0 +1,21 @@ +btnFileOpen=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 .NSP \u0444\u0430\u0439\u043B\u0438 +btnUpload=\u0412\u0456\u0434\u0456\u0441\u043B\u0430\u0442\u0438 \u0443 NS +logsEnteredAsMsg1=\u0412\u0438 \u0443\u0432\u0456\u0439\u0448\u043B\u0438 \u044F\u043A: +logsEnteredAsMsg2=\u0414\u043B\u044F \u0437\u0430\u043F\u043E\u0431\u0456\u0433\u0430\u043D\u043D\u044F \u043F\u043E\u043C\u0438\u043B\u043E\u043A \u0432\u0438 \u043C\u0430\u0454\u0442\u0435 \u0431\u0443\u0442\u0438 root \u0430\u0431\u043E \u043D\u0430\u0441\u0442\u0440\u043E\u0457\u0442\u0438 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 'udev' \u0434\u043B\u044F \u0446\u044C\u043E\u0433\u043E \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430. +logsFilesToUploadTitle=\u0424\u0430\u0439\u043B\u0438 \u0434\u043B\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F: +logsGreetingsMessage=\u041B\u0430\u0441\u043A\u0430\u0432\u043E \u043F\u0440\u043E\u0441\u0438\u043C\u043E \u0434\u043E NS-USBloader +logsNoFolderFileSelected=\u0424\u0430\u0439\u043B\u0438 \u043D\u0435 \u0432\u0438\u0431\u0440\u0430\u043D\u0456 - \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438 \u043D\u0456\u0447\u043E\u0433\u043E. +windowBodyConfirmExit=\u0417\u0430\u0440\u0430\u0437 \u0432\u0456\u0434\u0431\u0443\u0432\u0430\u0454\u0442\u044C\u0441\u044F \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043D\u0438\u0445 \u0456 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043D\u044F \u0434\u043E\u0434\u0430\u0442\u043A\u0443 \u043F\u0440\u0435\u0440\u0432\u0435 \u0457\u0457.\n\u0426\u0435 \u043D\u0430\u0439\u0433\u0456\u0440\u0448\u0435 \u0449\u043E \u0442\u0438 \u043C\u043E\u0436\u0435\u0448 \u0437\u0430\u0440\u0430\u0437 \u0437\u0440\u043E\u0431\u0438\u0442\u0438.\n\u041F\u0440\u0435\u0440\u0432\u0430\u0442\u0438 \u043F\u0440\u043E\u0446\u0435\u0441 \u0456 \u0432\u0438\u0439\u0442\u0438? +windowTitleConfirmExit=\u041D\u0456, \u0437\u0443\u043F\u0438\u043D\u0438\u0441\u044C! +btnStop=\u041F\u0435\u0440\u0435\u0440\u0432\u0430\u0442\u0438 +logsGreetingsMessage2=--\n\ +\u0421\u0438\u0440\u0446\u0435\u0432\u0438\u0439 \u043A\u043E\u0434: https://github.com/developersu/ns-usbloader/\n\ +\u0421\u0430\u0439\u0442: https://developersu.blogspot.com/search/label/NS-USBloader\n\ +\u0418\u0441\u0430\u0454\u043D\u043A\u043E \u0414\u043C\u0438\u0442\u0440\u043E [developer.su] +windowTitleConfirmWrongPFS0=\u041D\u0435\u0432\u0456\u0440\u043D\u0438\u0439 \u0442\u0438\u043F \u0444\u0430\u0439\u043B\u0443 +windowBodyConfirmWrongPFS0=\u0412\u0438\u0431\u0440\u0430\u043D\u0438\u0439 \u0444\u0430\u0439\u043B NSP \u043C\u0430\u0454 \u043D\u0435\u0432\u0456\u0440\u043D\u0456 \u0441\u0438\u043C\u0432\u043E\u043B\u0438. \u0421\u043A\u043E\u0440\u0456\u0448\u0435 \u0437\u0430 \u0432\u0441\u0435 \u0432\u0456\u043D \u043F\u043E\u0448\u043A\u043E\u0434\u0436\u0435\u043D\u0438\u0439.\n\ +\u041A\u0440\u0430\u0449\u0435 \u0437\u0443\u043F\u0438\u043D\u0438\u0442\u0438\u0441\u044F \u043F\u0440\u044F\u043C\u043E \u0437\u0430\u0440\u0430\u0437. \u0425\u043E\u0447\u0435\u0448 \u043F\u0440\u043E\u0434\u043E\u0432\u0436\u0438\u0442\u0438 \u043D\u0435 \u0437\u0432\u0430\u0436\u0430\u044E\u0447\u0438 \u043D\u0456 \u043D\u0430 \u0449\u043E? +tableStatusLbl=\u0421\u0442\u0430\u043D +tableFileNameLbl=\u0406\u043C'\u044F \u0444\u0430\u0439\u043B\u0443 +tableSizeLbl=\u0420\u043E\u0437\u043C\u0456\u0440 (~\u041C\u0431) +tableUploadLbl=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436.? \ No newline at end of file