v0.7 Add GLv0.7 support

This commit is contained in:
Dmitry Isaenko 2019-09-17 03:50:42 +03:00
parent a8b8bfa849
commit 56a53ef49b
6 changed files with 202 additions and 103 deletions

View file

@ -8,7 +8,7 @@
<name>NS-USBloader</name> <name>NS-USBloader</name>
<artifactId>ns-usbloader</artifactId> <artifactId>ns-usbloader</artifactId>
<version>0.6.1-SNAPSHOT</version> <version>0.7-SNAPSHOT</version>
<url>https://github.com/developersu/ns-usbloader/</url> <url>https://github.com/developersu/ns-usbloader/</url>
<description> <description>
@ -218,11 +218,11 @@
<minVersion>1.8</minVersion> <minVersion>1.8</minVersion>
</jre> </jre>
<versionInfo> <versionInfo>
<fileVersion>0.6.1.0</fileVersion> <fileVersion>0.7.0.0</fileVersion>
<txtFileVersion>${project.version}</txtFileVersion> <txtFileVersion>${project.version}</txtFileVersion>
<fileDescription>TinFoil and GoldLeaf installer for your NS</fileDescription> <fileDescription>TinFoil and GoldLeaf installer for your NS</fileDescription>
<copyright>GNU General Public License v3, 2019 ${organization.name}. Russia/LPR.</copyright> <copyright>GNU General Public License v3, 2019 ${organization.name}. Russia/LPR.</copyright>
<productVersion>0.6.1.0</productVersion> <productVersion>0.7.0.0</productVersion>
<txtProductVersion>${project.version}</txtProductVersion> <txtProductVersion>${project.version}</txtProductVersion>
<companyName>${organization.name}</companyName> <companyName>${organization.name}</companyName>
<productName>${project.name}</productName> <productName>${project.name}</productName>

View file

@ -92,6 +92,16 @@ public class NSLMainController implements Initializable {
updates.start(); updates.start();
} }
} }
/**
* Get resources
* TODO: Find better solution; used in UsbCommunications() -> GL -> SelectFile command
* @return ResourceBundle
*/
public ResourceBundle getResourceBundle() {
return resourceBundle;
}
/** /**
* Provide hostServices to Settings tab * Provide hostServices to Settings tab
* */ * */

View file

@ -12,7 +12,7 @@ import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class NSLMain extends Application { public class NSLMain extends Application {
public static final String appVersion = "v0.6.1"; public static final String appVersion = "v0.7";
@Override @Override
public void start(Stage primaryStage) throws Exception{ public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml"));

View file

@ -28,4 +28,16 @@ public class RainbowHexDump {
+ new String(byteArray, StandardCharsets.UTF_8) + new String(byteArray, StandardCharsets.UTF_8)
+ "\n"); + "\n");
} }
public static void hexDumpUTF16LE(byte[] byteArray){
System.out.print(ANSI_BLUE);
for (int i=0; i < byteArray.length; i++)
System.out.print(String.format("%02d-", i%100));
System.out.println(">"+ANSI_RED+byteArray.length+ANSI_RESET);
for (byte b: byteArray)
System.out.print(String.format("%02x ", b));
System.out.print("\t\t\t"
+ new String(byteArray, StandardCharsets.UTF_16LE)
+ "\n");
}
} }

View file

@ -1,6 +1,9 @@
package nsusbloader.USB; package nsusbloader.USB;
import javafx.application.Platform;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.stage.FileChooser;
import nsusbloader.MediatorControl;
import nsusbloader.ModelControllers.LogPrinter; import nsusbloader.ModelControllers.LogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.NSLDataTypes.EMsgType; import nsusbloader.NSLDataTypes.EMsgType;
@ -14,6 +17,8 @@ import java.nio.IntBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
// TODO: add filter option to show only NSP files // TODO: add filter option to show only NSP files
public class UsbCommunications extends Task<Void> { public class UsbCommunications extends Task<Void> {
private final int DEFAULT_INTERFACE = 0; private final int DEFAULT_INTERFACE = 0;
@ -204,6 +209,7 @@ public class UsbCommunications extends Task<Void> {
* */ * */
private class TinFoil{ private class TinFoil{
TinFoil(){ TinFoil(){
logPrinter.print("============= TinFoil =============", EMsgType.INFO);
if (!sendListOfNSP()) if (!sendListOfNSP())
return; return;
@ -432,6 +438,7 @@ public class UsbCommunications extends Task<Void> {
} }
} }
/** /**
* GoldLeaf processing * GoldLeaf processing
* */ * */
@ -457,6 +464,8 @@ public class UsbCommunications extends Task<Void> {
private boolean isWindows; private boolean isWindows;
private String homePath; private String homePath;
// For using in CMD_SelectFile with SPEC:/ prefix
private File selectedFile;
GoldLeaf(){ GoldLeaf(){
final byte CMD_GetDriveCount = 0x00; final byte CMD_GetDriveCount = 0x00;
@ -473,7 +482,7 @@ public class UsbCommunications extends Task<Void> {
final byte CMD_Rename = 0x0b;//11 final byte CMD_Rename = 0x0b;//11
final byte CMD_GetSpecialPathCount = 0x0c;//12 // Special folders count; simplified usage @ NS-UL final byte CMD_GetSpecialPathCount = 0x0c;//12 // Special folders count; simplified usage @ NS-UL
final byte CMD_GetSpecialPath = 0x0d;//13 // Information about special folders; simplified usage @ NS-UL final byte CMD_GetSpecialPath = 0x0d;//13 // Information about special folders; simplified usage @ NS-UL
final byte CMD_SelectFile = 0x0e;//14 // WTF? Ignoring for now. For future: execute another thread within this(?) context for FileChooser final byte CMD_SelectFile = 0x0e;//14
final byte CMD_Max = 0x0f;//15 // not used @ NS-UL & GT final byte CMD_Max = 0x0f;//15 // not used @ NS-UL & GT
final byte[] CMD_GLCI = new byte[]{0x47, 0x4c, 0x43, 0x49}; final byte[] CMD_GLCI = new byte[]{0x47, 0x4c, 0x43, 0x49};
@ -495,7 +504,8 @@ public class UsbCommunications extends Task<Void> {
// Go parse commands // Go parse commands
byte[] readByte; byte[] readByte;
int someLength; int someLength1,
someLength2;
while (! isCancelled()) { // Till user interrupted process. while (! isCancelled()) { // Till user interrupted process.
readByte = readGL(); readByte = readGL();
@ -506,8 +516,8 @@ public class UsbCommunications extends Task<Void> {
continue; continue;
} }
//RainbowHexDump.hexDumpUTF8(readByte); // TODO: DEBUG //RainbowHexDump.hexDumpUTF16LE(readByte); // DEBUG
//System.out.println("CHOICE: "+readByte[4]); // TODO: DEBUG //System.out.println("CHOICE: "+readByte[4]); // DEBUG
if (Arrays.equals(Arrays.copyOfRange(readByte, 0,4), CMD_GLCI)) { if (Arrays.equals(Arrays.copyOfRange(readByte, 0,4), CMD_GLCI)) {
switch (readByte[4]) { switch (readByte[4]) {
@ -528,52 +538,62 @@ public class UsbCommunications extends Task<Void> {
return; return;
break; break;
case CMD_GetDirectoryCount: case CMD_GetDirectoryCount:
if (getDirectoryOrFileCount(new String(readByte, 12, arrToIntLE(readByte, 8), StandardCharsets.UTF_8), true)) someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (getDirectoryOrFileCount(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE), true))
return; return;
break; break;
case CMD_GetFileCount: case CMD_GetFileCount:
if (getDirectoryOrFileCount(new String(readByte, 12, arrToIntLE(readByte, 8), StandardCharsets.UTF_8), false)) someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (getDirectoryOrFileCount(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE), false))
return; return;
break; break;
case CMD_GetDirectory: case CMD_GetDirectory:
someLength = arrToIntLE(readByte, 8); someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (getDirectory(new String(readByte, 12, someLength, StandardCharsets.UTF_8), arrToIntLE(readByte, someLength+12))) if (getDirectory(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE), arrToIntLE(readByte, someLength1+12)))
return; return;
break; break;
case CMD_GetFile: case CMD_GetFile:
someLength = arrToIntLE(readByte, 8); someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (getFile(new String(readByte, 12, someLength, StandardCharsets.UTF_8), arrToIntLE(readByte, someLength+12))) if (getFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE), arrToIntLE(readByte, someLength1+12)))
return; return;
break; break;
case CMD_StatPath: case CMD_StatPath:
if (statPath(new String(readByte, 12, arrToIntLE(readByte, 8), StandardCharsets.UTF_8))) someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (statPath(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE)))
return; return;
break; break;
case CMD_Rename: case CMD_Rename:
someLength = arrToIntLE(readByte, 12); someLength1 = arrToIntLE(readByte, 12) * 2; // Since GL 0.7
if (rename(new String(readByte, 16, someLength, StandardCharsets.UTF_8), someLength2 = arrToIntLE(readByte, 16+someLength1) * 2; // Since GL 0.7
new String(readByte, 16+someLength+4, arrToIntLE(readByte, 16+someLength), StandardCharsets.UTF_8))) if (rename(new String(readByte, 16, someLength1, StandardCharsets.UTF_16LE),
new String(readByte, 16+someLength1+4, someLength2, StandardCharsets.UTF_16LE)))
return; return;
break; break;
case CMD_Delete: case CMD_Delete:
if (delete(new String(readByte, 16, arrToIntLE(readByte, 12), StandardCharsets.UTF_8))) someLength1 = arrToIntLE(readByte, 12) * 2; // Since GL 0.7
if (delete(new String(readByte, 16, someLength1, StandardCharsets.UTF_16LE)))
return; return;
break; break;
case CMD_Create: case CMD_Create:
if (create(new String(readByte, 16, arrToIntLE(readByte, 12), StandardCharsets.UTF_8), readByte[8])) someLength1 = arrToIntLE(readByte, 12) * 2; // Since GL 0.7
if (create(new String(readByte, 16, someLength1, StandardCharsets.UTF_16LE), readByte[8]))
return; return;
break; break;
case CMD_ReadFile: case CMD_ReadFile:
someLength = arrToIntLE(readByte, 8); someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (readFile(new String(readByte, 12, someLength, StandardCharsets.UTF_8), if (readFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE),
arrToLongLE(readByte, 12+someLength), arrToLongLE(readByte, 12+someLength1),
arrToLongLE(readByte, 12+someLength+8))) arrToLongLE(readByte, 12+someLength1+8)))
return; return;
break; break;
case CMD_WriteFile: case CMD_WriteFile:
someLength = arrToIntLE(readByte, 8); someLength1 = arrToIntLE(readByte, 8) * 2; // Since GL 0.7
if (writeFile(new String(readByte, 12, someLength, StandardCharsets.UTF_8), if (writeFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_16LE),
arrToLongLE(readByte, 12+someLength))) arrToLongLE(readByte, 12+someLength1)))
return;
break;
case CMD_SelectFile:
if (selectFile())
return; return;
break; break;
default: default:
@ -612,7 +632,7 @@ public class UsbCommunications extends Task<Void> {
*/ */
private boolean getDriveCount(){ private boolean getDriveCount(){
// Let's declare 2 drives // Let's declare 2 drives
byte[] drivesCnt = intToArrLE(2);//2 byte[] drivesCnt = intToArrLE(2); //2
// Write count of drives // Write count of drives
if (writeGL_PASS(drivesCnt)) { if (writeGL_PASS(drivesCnt)) {
logPrinter.print("GL Handle 'ListDrives' command", EMsgType.FAIL); logPrinter.print("GL Handle 'ListDrives' command", EMsgType.FAIL);
@ -640,10 +660,10 @@ public class UsbCommunications extends Task<Void> {
// 0 == VIRTUAL DRIVE // 0 == VIRTUAL DRIVE
if (driveNo == 0){ if (driveNo == 0){
driveLabel = "Virtual".getBytes(StandardCharsets.UTF_8); driveLabel = "Virtual".getBytes(StandardCharsets.UTF_16LE);
driveLabelLen = intToArrLE(driveLabel.length); driveLabelLen = intToArrLE(driveLabel.length / 2); // since GL 0.7
driveLetter = "VIRT".getBytes(StandardCharsets.UTF_8); // TODO: Consider moving to class field declaration driveLetter = "VIRT".getBytes(StandardCharsets.UTF_16LE); // TODO: Consider moving to class field declaration
driveLetterLen = intToArrLE(driveLetter.length); driveLetterLen = intToArrLE(driveLetter.length / 2);// since GL 0.7
totalFreeSpace = new byte[4]; totalFreeSpace = new byte[4];
for (File nspFile : nspMap.values()){ for (File nspFile : nspMap.values()){
totalSizeLong += nspFile.length(); totalSizeLong += nspFile.length();
@ -651,15 +671,17 @@ public class UsbCommunications extends Task<Void> {
totalSize = Arrays.copyOfRange(longToArrLE(totalSizeLong), 0, 4); // Dirty hack; now for GL! totalSize = Arrays.copyOfRange(longToArrLE(totalSizeLong), 0, 4); // Dirty hack; now for GL!
} }
else { //1 == User home dir else { //1 == User home dir
driveLabel = "Home".getBytes(StandardCharsets.UTF_8); driveLabel = "Home".getBytes(StandardCharsets.UTF_16LE);
driveLabelLen = intToArrLE(driveLabel.length); driveLabelLen = intToArrLE(driveLabel.length / 2);// since GL 0.7
driveLetter = "HOME".getBytes(StandardCharsets.UTF_8); driveLetter = "HOME".getBytes(StandardCharsets.UTF_16LE);
driveLetterLen = intToArrLE(driveLetter.length); driveLetterLen = intToArrLE(driveLetter.length / 2);// since GL 0.7
File userHomeDir = new File(System.getProperty("user.home")); File userHomeDir = new File(System.getProperty("user.home"));
long totalFreeSpaceLong = userHomeDir.getFreeSpace(); long totalFreeSpaceLong = userHomeDir.getFreeSpace();
totalFreeSpace = Arrays.copyOfRange(longToArrLE(totalFreeSpaceLong), 0, 4); // Dirty hack; now for GL!; totalFreeSpace = Arrays.copyOfRange(longToArrLE(totalFreeSpaceLong), 0, 4); // Dirty hack; now for GL!;
totalSizeLong = userHomeDir.getTotalSpace(); totalSizeLong = userHomeDir.getTotalSpace();
totalSize = Arrays.copyOfRange(longToArrLE(totalSizeLong), 0, 4); // Dirty hack; now for GL! totalSize = Arrays.copyOfRange(longToArrLE(totalSizeLong), 0, 4); // Dirty hack; now for GL!
//System.out.println("totalSize: "+totalSizeLong+"totalFreeSpace: "+totalFreeSpaceLong);
} }
List<byte[]> command = new LinkedList<>(); List<byte[]> command = new LinkedList<>();
@ -684,9 +706,9 @@ public class UsbCommunications extends Task<Void> {
* */ * */
private boolean getSpecialPathCount(){ private boolean getSpecialPathCount(){
// Let's declare nothing =) // Let's declare nothing =)
byte[] virtDrivesCnt = intToArrLE(0); byte[] specialPathCnt = intToArrLE(0);
// Write count of special paths // Write count of special paths
if (writeGL_PASS(virtDrivesCnt)) { if (writeGL_PASS(specialPathCnt)) {
logPrinter.print("GL Handle 'SpecialPathCount' command", EMsgType.FAIL); logPrinter.print("GL Handle 'SpecialPathCount' command", EMsgType.FAIL);
return true; return true;
} }
@ -697,7 +719,7 @@ public class UsbCommunications extends Task<Void> {
* @return true if failed * @return true if failed
* false if everything is ok * false if everything is ok
* */ * */
private boolean getSpecialPath(int virtDriveNo){ private boolean getSpecialPath(int specialPathNo){
return writeGL_FAIL("GL Handle 'SpecialPath' command [not supported]"); return writeGL_FAIL("GL Handle 'SpecialPath' command [not supported]");
} }
/** /**
@ -736,20 +758,20 @@ public class UsbCommunications extends Task<Void> {
if (isGetDirectoryCount){ if (isGetDirectoryCount){
filesOrDirs = pathDir.list((current, name) -> { filesOrDirs = pathDir.list((current, name) -> {
File dir = new File(current, name); File dir = new File(current, name);
return (dir.isDirectory() && ! dir.isHidden()); // TODO: FIX FOR WIN ? return (dir.isDirectory() && ! dir.isHidden());
}); });
} }
else { else {
if (nspFilterForGl){ if (nspFilterForGl){
filesOrDirs = pathDir.list((current, name) -> { filesOrDirs = pathDir.list((current, name) -> {
File dir = new File(current, name); File dir = new File(current, name);
return (! dir.isDirectory() && name.toLowerCase().endsWith(".nsp")); // TODO: FIX FOR WIN ? return (! dir.isDirectory() && name.toLowerCase().endsWith(".nsp"));
}); });
} }
else { else {
filesOrDirs = pathDir.list((current, name) -> { filesOrDirs = pathDir.list((current, name) -> {
File dir = new File(current, name); File dir = new File(current, name);
return (! dir.isDirectory() && (! dir.isHidden())); // TODO: MOVE TO PROD return (! dir.isDirectory() && (! dir.isHidden()));
}); });
} }
} }
@ -759,10 +781,9 @@ public class UsbCommunications extends Task<Void> {
logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL);
return true; return true;
} }
//logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.PASS);
return false; return false;
} }
// Sorting is mandatory // Sorting is mandatory TODO: NOTE: Proxy tail
Arrays.sort(filesOrDirs, String.CASE_INSENSITIVE_ORDER); Arrays.sort(filesOrDirs, String.CASE_INSENSITIVE_ORDER);
if (isGetDirectoryCount) if (isGetDirectoryCount)
@ -775,9 +796,24 @@ public class UsbCommunications extends Task<Void> {
return true; return true;
} }
} }
// If requested drive is not VIRT and not HOME then reply error else if (path.startsWith("SPEC:/")){
else { if (isGetDirectoryCount){ // If dir request then 0 dirs
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request]"); if (writeGL_PASS()) {
logPrinter.print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL);
return true;
}
}
else if (selectedFile != null){ // Else it's file request, if we have selected then we will report 1.
if (writeGL_PASS(intToArrLE(1))) {
logPrinter.print("GL Handle 'GetFileCount' command Count = 1", EMsgType.FAIL);
return true;
}
}
else
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request] (file) - "+path);
}
else { // If requested drive is not VIRT and not HOME then reply error
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request] "+(isGetDirectoryCount?"(dir) - ":"(file) - ")+path);
} }
return false; return false;
} }
@ -793,8 +829,10 @@ public class UsbCommunications extends Task<Void> {
List<byte[]> command = new LinkedList<>(); List<byte[]> command = new LinkedList<>();
if (dirName.equals(recentPath) && recentDirs != null && recentDirs.length != 0){ if (dirName.equals(recentPath) && recentDirs != null && recentDirs.length != 0){
command.add(intToArrLE(recentDirs[subDirNo].getBytes(StandardCharsets.UTF_8).length)); byte[] dirNameBytes = recentDirs[subDirNo].getBytes(StandardCharsets.UTF_16LE);
command.add(recentDirs[subDirNo].getBytes(StandardCharsets.UTF_8));
command.add(intToArrLE(dirNameBytes.length / 2)); // Since GL 0.7
command.add(dirNameBytes);
} }
else { else {
File pathDir = new File(dirName); File pathDir = new File(dirName);
@ -810,22 +848,21 @@ public class UsbCommunications extends Task<Void> {
// Check that we still don't have any fuckups // Check that we still don't have any fuckups
if (this.recentDirs != null && this.recentDirs.length > subDirNo){ if (this.recentDirs != null && this.recentDirs.length > subDirNo){
Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER); Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER);
byte[] dirBytesName = recentDirs[subDirNo].getBytes(StandardCharsets.UTF_8); byte[] dirBytesName = recentDirs[subDirNo].getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(dirBytesName.length)); command.add(intToArrLE(dirBytesName.length / 2)); // Since GL 0.7
command.add(dirBytesName); command.add(dirBytesName);
} }
else else
return writeGL_FAIL("GL Handle 'GetDirectory' command [doesn't exist or not a folder]"); return writeGL_FAIL("GL Handle 'GetDirectory' command [doesn't exist or not a folder]");
} }
if (proxyForGL) //if (proxyForGL) // TODO: NOTE: PROXY TAILS
return proxyGetDirFile(true); // return proxyGetDirFile(true);
else {
if (writeGL_PASS(command)) { if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'GetDirectory' command.", EMsgType.FAIL); logPrinter.print("GL Handle 'GetDirectory' command.", EMsgType.FAIL);
return true; return true;
}
return false;
} }
return false;
} }
// VIRT:// and any other // VIRT:// and any other
return writeGL_FAIL("GL Handle 'GetDirectory' command for virtual drive [no folders support]"); return writeGL_FAIL("GL Handle 'GetDirectory' command for virtual drive [no folders support]");
@ -842,9 +879,9 @@ public class UsbCommunications extends Task<Void> {
dirName = updateHomePath(dirName); dirName = updateHomePath(dirName);
if (dirName.equals(recentPath) && recentFiles != null && recentFiles.length != 0){ if (dirName.equals(recentPath) && recentFiles != null && recentFiles.length != 0){
byte[] fileNameBytes = recentFiles[subDirNo].getBytes(StandardCharsets.UTF_8); byte[] fileNameBytes = recentFiles[subDirNo].getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(fileNameBytes.length)); command.add(intToArrLE(fileNameBytes.length / 2)); //Since GL 0.7
command.add(fileNameBytes); command.add(fileNameBytes);
} }
else { else {
@ -869,16 +906,26 @@ public class UsbCommunications extends Task<Void> {
// Check that we still don't have any fuckups // Check that we still don't have any fuckups
if (this.recentFiles != null && this.recentFiles.length > subDirNo){ if (this.recentFiles != null && this.recentFiles.length > subDirNo){
Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER); // TODO: NOTE: array sorting is an overhead for using poxy loops Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER); // TODO: NOTE: array sorting is an overhead for using poxy loops
byte[] fileNameBytes = recentFiles[subDirNo].getBytes(StandardCharsets.UTF_8); byte[] fileNameBytes = recentFiles[subDirNo].getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(fileNameBytes.length)); command.add(intToArrLE(fileNameBytes.length / 2)); //Since GL 0.7
command.add(fileNameBytes); command.add(fileNameBytes);
} }
else else
return writeGL_FAIL("GL Handle 'GetFile' command [doesn't exist or not a folder]"); return writeGL_FAIL("GL Handle 'GetFile' command [doesn't exist or not a folder]");
} }
if (proxyForGL) //if (proxyForGL) // TODO: NOTE: PROXY TAILS
return proxyGetDirFile(false); // return proxyGetDirFile(false);
else { if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL);
return true;
}
return false;
}
else if (dirName.equals("VIRT:/")){
if (nspMap.size() != 0){ // therefore nspMapKeySetIndexes also != 0
byte[] fileNameBytes = nspMapKeySetIndexes[subDirNo].getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(fileNameBytes.length / 2)); // since GL 0.7
command.add(fileNameBytes);
if (writeGL_PASS(command)) { if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL);
return true; return true;
@ -886,10 +933,10 @@ public class UsbCommunications extends Task<Void> {
return false; return false;
} }
} }
else if (dirName.equals("VIRT:/")){ else if (dirName.equals("SPEC:/")){
if (nspMap.size() != 0){ // therefore nspMapKeySetIndexes also != 0 if (selectedFile != null){
byte[] fileNameBytes = nspMapKeySetIndexes[subDirNo].getBytes(StandardCharsets.UTF_8); byte[] fileNameBytes = selectedFile.getName().getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(fileNameBytes.length)); command.add(intToArrLE(fileNameBytes.length / 2)); // since GL 0.7
command.add(fileNameBytes); command.add(fileNameBytes);
if (writeGL_PASS(command)) { if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL);
@ -899,7 +946,7 @@ public class UsbCommunications extends Task<Void> {
} }
} }
// any other cases // any other cases
return writeGL_FAIL("GL Handle 'GetFile' command for virtual drive [no folders support]"); return writeGL_FAIL("GL Handle 'GetFile' command for virtual drive [no folders support?]");
} }
/** /**
* Handle StatPath * Handle StatPath
@ -911,8 +958,8 @@ public class UsbCommunications extends Task<Void> {
if (filePath.startsWith("HOME:/")){ if (filePath.startsWith("HOME:/")){
filePath = updateHomePath(filePath); filePath = updateHomePath(filePath);
if (proxyForGL) //if (proxyForGL) // TODO:NOTE PROXY TAILS
return proxyStatPath(filePath); // dirty name // return proxyStatPath(filePath); // dirty name
File fileDirElement = new File(filePath); File fileDirElement = new File(filePath);
if (fileDirElement.exists()){ if (fileDirElement.exists()){
@ -941,6 +988,19 @@ public class UsbCommunications extends Task<Void> {
return false; return false;
} }
} }
else if (filePath.startsWith("SPEC:/")){
System.out.println(filePath);
filePath = filePath.replaceFirst("SPEC:/","");
if (selectedFile.getName().equals(filePath)){
command.add(GL_OBJ_TYPE_FILE);
command.add(longToArrLE(selectedFile.length()));
if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL);
return true;
}
return false;
}
}
return writeGL_FAIL("GL Handle 'StatPath' command [no such folder] - "+filePath); return writeGL_FAIL("GL Handle 'StatPath' command [no such folder] - "+filePath);
} }
/** /**
@ -1046,6 +1106,7 @@ public class UsbCommunications extends Task<Void> {
* false if everything is ok * false if everything is ok
* */ * */
private boolean readFile(String fileName, long offset, long size) { private boolean readFile(String fileName, long offset, long size) {
//System.out.println("readFile "+fileName+" "+offset+" "+size);
if (fileName.startsWith("VIRT:/")){ if (fileName.startsWith("VIRT:/")){
// Let's find out which file requested // Let's find out which file requested
String fNamePath = nspMap.get(fileName.substring(6)).getAbsolutePath(); // NOTE: 6 = "VIRT:/".length String fNamePath = nspMap.get(fileName.substring(6)).getAbsolutePath(); // NOTE: 6 = "VIRT:/".length
@ -1101,22 +1162,9 @@ public class UsbCommunications extends Task<Void> {
logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL);
return true; return true;
} }
if (bytesRead > 8388608){
// Let's bypass bytes we read part 1
if (writeToUsb(Arrays.copyOfRange(chunk, 0, 8388608))) {
logPrinter.print("GL Handle 'ReadFile' command [Data 1/2]", EMsgType.FAIL);
return true;
}
// Let's bypass bytes we read part 2
if (writeToUsb(Arrays.copyOfRange(chunk, 8388608, chunk.length))) {
logPrinter.print("GL Handle 'ReadFile' command [Data 2/2]", EMsgType.FAIL);
return true;
}
return false;
}
// Let's bypass bytes we read total // Let's bypass bytes we read total
if (writeToUsb(chunk)) { if (writeToUsb(chunk)) {
logPrinter.print("GL Handle 'ReadFile' command [Data 1/1]", EMsgType.FAIL); logPrinter.print("GL Handle 'ReadFile' command", EMsgType.FAIL);
return true; return true;
} }
return false; return false;
@ -1141,15 +1189,11 @@ public class UsbCommunications extends Task<Void> {
* false if everything is ok * false if everything is ok
* */ * */
private boolean writeFile(String fileName, long size) { private boolean writeFile(String fileName, long size) {
//System.out.println("writeFile "+fileName+" "+size);
if (fileName.startsWith("VIRT:/")){ if (fileName.startsWith("VIRT:/")){
return writeGL_FAIL("GL Handle 'WriteFile' command [not supported for virtual drive]"); return writeGL_FAIL("GL Handle 'WriteFile' command [not supported for virtual drive]");
} }
else { else {
if ((int)size > 8388608){
logPrinter.print("GL Handle 'WriteFile' command [Files greater than 8mb are not supported]", EMsgType.FAIL);
return true;
}
fileName = updateHomePath(fileName); fileName = updateHomePath(fileName);
// Check if we didn't see this (or any) file during this session // Check if we didn't see this (or any) file during this session
if (writeFilesMap.size() == 0 || (! writeFilesMap.containsKey(fileName))){ if (writeFilesMap.size() == 0 || (! writeFilesMap.containsKey(fileName))){
@ -1188,6 +1232,38 @@ public class UsbCommunications extends Task<Void> {
} }
} }
/**
* Handle 'SelectFile'
* @return true if failed
* false if everything is ok
* */
private boolean selectFile(){
File selectedFile = CompletableFuture.supplyAsync(() -> {
FileChooser fChooser = new FileChooser();
fChooser.setTitle(MediatorControl.getInstance().getContoller().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
fChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: Consider fixing; not a prio.
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
return fChooser.showOpenDialog(null); // Leave as is for now.
}, Platform::runLater).join();
if (selectedFile != null){
List<byte[]> command = new LinkedList<>();
byte[] selectedFileNameBytes = ("SPEC:/"+selectedFile.getName()).getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(selectedFileNameBytes.length / 2)); // since GL 0.7
command.add(selectedFileNameBytes);
if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'SelectFile' command", EMsgType.FAIL);
this.selectedFile = null;
return true;
}
this.selectedFile = selectedFile;
return false;
}
// Nothing selected; Report failure.
this.selectedFile = null;
return writeGL_FAIL("GL Handle 'SelectFile' command: Nothing selected");
}
/*----------------------------------------------------*/ /*----------------------------------------------------*/
/* GL READ/WRITE USB SPECIFIC */ /* GL READ/WRITE USB SPECIFIC */
/*----------------------------------------------------*/ /*----------------------------------------------------*/
@ -1226,7 +1302,7 @@ public class UsbCommunications extends Task<Void> {
IntBuffer readBufTransferred = IntBuffer.allocate(1); IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result; int result;
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 5000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81 result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
if (result != LibUsb.SUCCESS && result != LibUsb.ERROR_TIMEOUT){ if (result != LibUsb.SUCCESS && result != LibUsb.ERROR_TIMEOUT){
logPrinter.print("GL Data transfer (read) issue\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); logPrinter.print("GL Data transfer (read) issue\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
@ -1246,7 +1322,7 @@ public class UsbCommunications extends Task<Void> {
IntBuffer readBufTransferred = IntBuffer.allocate(1); // Works for 8mb IntBuffer readBufTransferred = IntBuffer.allocate(1); // Works for 8mb
int result; int result;
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 0); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81 result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 5000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81 TODO: Fix or leave as is
if (result != LibUsb.SUCCESS && result != LibUsb.ERROR_TIMEOUT){ if (result != LibUsb.SUCCESS && result != LibUsb.ERROR_TIMEOUT){
logPrinter.print("GL Data transfer (read) issue\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); logPrinter.print("GL Data transfer (read) issue\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
@ -1302,9 +1378,10 @@ public class UsbCommunications extends Task<Void> {
} }
/*----------------------------------------------------*/ /*----------------------------------------------------*/
/* GL EXPERIMENTAL PART */ /* GL EXPERIMENTAL PART */
/* (left for better times) */
/*----------------------------------------------------*/ /*----------------------------------------------------*/
/*
private boolean proxyStatPath(String path) { private boolean proxyStatPath(String path) {
ByteBuffer writeBuffer = ByteBuffer.allocate(4096); ByteBuffer writeBuffer = ByteBuffer.allocate(4096);
List<byte[]> fileBytesSize = new LinkedList<>(); List<byte[]> fileBytesSize = new LinkedList<>();
@ -1348,7 +1425,7 @@ public class UsbCommunications extends Task<Void> {
if (recentDirs.length <= 0) if (recentDirs.length <= 0)
return writeGL_FAIL("proxyGetDirFile"); return writeGL_FAIL("proxyGetDirFile");
for (String dirName : recentDirs) { for (String dirName : recentDirs) {
byte[] name = dirName.getBytes(StandardCharsets.UTF_8); byte[] name = dirName.getBytes(StandardCharsets.UTF_16LE);
dirBytesNameSize.add(intToArrLE(name.length)); dirBytesNameSize.add(intToArrLE(name.length));
dirBytesName.add(name); dirBytesName.add(name);
} }
@ -1370,7 +1447,7 @@ public class UsbCommunications extends Task<Void> {
if (recentDirs.length <= 0) if (recentDirs.length <= 0)
return writeGL_FAIL("proxyGetDirFile"); return writeGL_FAIL("proxyGetDirFile");
for (String dirName : recentFiles){ for (String dirName : recentFiles){
byte[] name = dirName.getBytes(StandardCharsets.UTF_8); byte[] name = dirName.getBytes(StandardCharsets.UTF_16LE);
dirBytesNameSize.add(intToArrLE(name.length)); dirBytesNameSize.add(intToArrLE(name.length));
dirBytesName.add(name); dirBytesName.add(name);
} }
@ -1390,9 +1467,8 @@ public class UsbCommunications extends Task<Void> {
} }
return false; return false;
} }
*/
} }
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
/** /**
* Correct exit * Correct exit
@ -1429,8 +1505,9 @@ public class UsbCommunications extends Task<Void> {
* */ * */
private boolean writeToUsb(byte[] message){ private boolean writeToUsb(byte[] message){
ByteBuffer writeBuffer = ByteBuffer.allocateDirect(message.length); //writeBuffer.order() equals BIG_ENDIAN; ByteBuffer writeBuffer = ByteBuffer.allocateDirect(message.length); //writeBuffer.order() equals BIG_ENDIAN;
writeBuffer.put(message); writeBuffer.put(message);// DONT EVEN THINK OF USING writeBuffer.rewind(); // well..
// DONT EVEN THINK OF USING writeBuffer.rewind(); // well.. //RainbowHexDump.hexDumpUTF16LE(message);
//System.out.println("-------------------");
IntBuffer writeBufTransferred = IntBuffer.allocate(1); IntBuffer writeBufTransferred = IntBuffer.allocate(1);
int result; int result;
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 0); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01 result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 0); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01

View file

@ -68,7 +68,7 @@
</graphic> </graphic>
</Button> </Button>
<Pane HBox.hgrow="ALWAYS" /> <Pane HBox.hgrow="ALWAYS" />
<Button fx:id="uploadStopBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" prefWidth="130.0" text="%btn_Upload"> <Button fx:id="uploadStopBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_Upload">
<HBox.margin> <HBox.margin>
<Insets /> <Insets />
</HBox.margin> </HBox.margin>