Rolling GL v0.8 support.

Bug fix for #41
This commit is contained in:
Dmitry Isaenko 2020-01-13 22:49:50 +03:00
parent ee478dfc9f
commit 5408d66a9e
7 changed files with 1274 additions and 139 deletions

View file

@ -47,12 +47,16 @@ JRE/JDK 8u60 or higher.
| GoldLeaf version | NS-USBloader version | | GoldLeaf version | NS-USBloader version |
| ---------------- | -------------------- | | ---------------- | -------------------- |
| v0.5 | v0.4 - v0.5.2, v0.8+ | | v0.5 | v0.4 - v0.5.2, v0.8+ |
| v0.6 | none |
| v0.6.1 | v0.6 | | v0.6.1 | v0.6 |
| v0.7 - 0.7.3 | v0.7 - v0.8+ | | v0.7 - 0.7.3 | v0.7+ |
| v0.8 | v1.0+ |
### Awoo support where '+' means 'any next NS-USBloader version'.
Awoo-installer uses the same command-set (or 'protocol') to TinFoil. So just select 'TinFoil' in case you're going to use Awoo. ### Awoo Installer support
Awoo Installer uses the same command-set (or 'protocol') to TinFoil. So just select 'TinFoil' in case you're going to use Awoo.
Also, please go to 'Settings' tab of NS-USBloader after first installation and check 'Allow XCI / NSZ / XCZ files selection for TinFoil' option. This installer can install not only NSPs but a way more formats! Also, please go to 'Settings' tab of NS-USBloader after first installation and check 'Allow XCI / NSZ / XCZ files selection for TinFoil' option. This installer can install not only NSPs but a way more formats!
@ -63,13 +67,15 @@ Also, please go to 'Settings' tab of NS-USBloader after first installation and c
2. `root # java -jar /path/to/NS-USBloader.jar` 2. `root # java -jar /path/to/NS-USBloader.jar`
3. Optional. Add user to 'udev' rules to use NS not-from-root-account 3. Optional: add user to 'udev' rules to use NS not-from-root-account
``` ```
root # vim /etc/udev/rules.d/99-NS.rules root # vim /etc/udev/rules.d/99-NS.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev" SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev"
root # udevadm control --reload-rules && udevadm trigger root # udevadm control --reload-rules && udevadm trigger
``` ```
Please note: you may have to change 'plugdev' group from example above to the different one. It's depends on you linux distro.
##### macOS ##### macOS
Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' section. Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' section.

View file

@ -8,7 +8,7 @@
<name>NS-USBloader</name> <name>NS-USBloader</name>
<artifactId>ns-usbloader</artifactId> <artifactId>ns-usbloader</artifactId>
<version>0.9.1-SNAPSHOT</version> <version>1.0.0-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.8.0.0</fileVersion> <fileVersion>1.0.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.8.0.0</productVersion> <productVersion>1.0.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

@ -19,14 +19,14 @@ import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
/** /**
* GoldLeaf 0.7 - 0.7.3 processing * GoldLeaf 0.8 processing
*/ */
class GoldLeaf extends TransferModule { class GoldLeaf extends TransferModule {
private boolean nspFilterForGl; private boolean nspFilterForGl;
// CMD // CMD
private final byte[] CMD_GLCO_SUCCESS = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, 0x00, 0x00}; // used @ writeToUsb_GLCMD private final byte[] CMD_GLCO_SUCCESS = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, 0x00, 0x00}; // used @ writeToUsb_GLCMD
private final byte[] CMD_GLCO_FAILURE = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x64, (byte) 0xcb, 0x00, 0x00}; // used @ writeToUsb_GLCMD private final byte[] CMD_GLCO_FAILURE = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, (byte) 0xAD, (byte) 0xDE}; // used @ writeToUsb_GLCMD TODO: TEST
// System.out.println((356 & 0x1FF) | ((1 + 100) & 0x1FFF) << 9); // 52068 // 0x00 0x00 0xCB 0x64 // System.out.println((356 & 0x1FF) | ((1 + 100) & 0x1FFF) << 9); // 52068 // 0x00 0x00 0xCB 0x64
private final byte[] GL_OBJ_TYPE_FILE = new byte[]{0x01, 0x00, 0x00, 0x00}; private final byte[] GL_OBJ_TYPE_FILE = new byte[]{0x01, 0x00, 0x00, 0x00};
@ -54,28 +54,31 @@ class GoldLeaf extends TransferModule {
GoldLeaf(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Task<Void> task, LogPrinter logPrinter, boolean nspFilter){ GoldLeaf(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Task<Void> task, LogPrinter logPrinter, boolean nspFilter){
super(handler, nspMap, task, logPrinter); super(handler, nspMap, task, logPrinter);
final byte CMD_GetDriveCount = 0x00; final byte CMD_GetDriveCount = 1;
final byte CMD_GetDriveInfo = 0x01; final byte CMD_GetDriveInfo = 2;
final byte CMD_StatPath = 0x02; // proxy done [proxy: in case if folder contains ENG+RUS+UKR file names works incorrect] final byte CMD_StatPath = 3;
final byte CMD_GetFileCount = 0x03; final byte CMD_GetFileCount = 4;
final byte CMD_GetFile = 0x04; // proxy done final byte CMD_GetFile = 5;
final byte CMD_GetDirectoryCount = 0x05; final byte CMD_GetDirectoryCount = 6;
final byte CMD_GetDirectory = 0x06; // proxy done final byte CMD_GetDirectory = 7;
final byte CMD_ReadFile = 0x07; // no way to do poxy final byte CMD_StartFile = 8; // 1 -open read RAF; 2 open write RAF; 3 open write RAF and seek to EOF (???).
final byte CMD_WriteFile = 0x08; // add predictable behavior final byte CMD_ReadFile = 9;
final byte CMD_Create = 0x09; final byte CMD_WriteFile = 10;
final byte CMD_Delete = 0x0a;//10 final byte CMD_EndFile = 11; // 1 - closed read RAF; 2 close write RAF.
final byte CMD_Rename = 0x0b;//11 final byte CMD_Create = 12;
final byte CMD_GetSpecialPathCount = 0x0c;//12 // Special folders count; simplified usage @ NS-UL final byte CMD_Delete = 13;
final byte CMD_GetSpecialPath = 0x0d;//13 // Information about special folders; simplified usage @ NS-UL final byte CMD_Rename = 14;
final byte CMD_SelectFile = 0x0e;//14 final byte CMD_GetSpecialPathCount = 15;
//final byte CMD_Max = 0x0f;//15 // not used @ NS-UL & GT final byte CMD_GetSpecialPath = 16;
final byte CMD_SelectFile = 17;
final byte[] CMD_GLCI = new byte[]{0x47, 0x4c, 0x43, 0x49}; final byte[] CMD_GLCI = new byte[]{0x47, 0x4c, 0x43, 0x49};
this.nspFilterForGl = nspFilter; this.nspFilterForGl = nspFilter;
logPrinter.print("============= GoldLeaf =============\n\tVIRT:/ equals files added into the application\n\tHOME:/ equals " logPrinter.print("============= GoldLeaf v0.8 =============\n\t" +
"VIRT:/ equals files added into the application\n\t" +
"HOME:/ equals "
+System.getProperty("user.home"), EMsgType.INFO); +System.getProperty("user.home"), EMsgType.INFO);
// Let's collect file names to the array to simplify our life // Let's collect file names to the array to simplify our life
@ -196,6 +199,11 @@ class GoldLeaf extends TransferModule {
if (selectFile()) if (selectFile())
break main_loop; break main_loop;
break; break;
case CMD_StartFile:
case CMD_EndFile:
if (startOrEndFile())
break main_loop;
break;
default: default:
writeGL_FAIL("GL Unknown command: "+readByte[4]+" [it's a very bad sign]"); writeGL_FAIL("GL Unknown command: "+readByte[4]+" [it's a very bad sign]");
} }
@ -230,6 +238,19 @@ class GoldLeaf extends TransferModule {
splitReader = null; splitReader = null;
} }
} }
/**
* Handle StartFile & EndFile
* NOTE: It's something internal for GL and used somehow by GL-PC-app, so just ignore this, at least for v0.8.
* @return true if failed
* false if everything is ok
* */
private boolean startOrEndFile(){
if (writeGL_PASS()){
logPrinter.print("GL Handle 'StartFile' command", EMsgType.FAIL);
return true;
}
return false;
}
/** /**
* Handle GetDriveCount * Handle GetDriveCount
* @return true if failed * @return true if failed
@ -714,7 +735,7 @@ class GoldLeaf extends TransferModule {
* 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+"\n"); //System.out.println("readFile "+fileName+"\t"+offset+"\t"+size+"\n");
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
@ -776,8 +797,10 @@ class GoldLeaf extends TransferModule {
int bytesRead = splitReader.read(chunk); int bytesRead = splitReader.read(chunk);
// Let's check that we read expected size // Let's check that we read expected size
if (bytesRead != (int)size) if (bytesRead != (int)size)
return writeGL_FAIL("GL Handle 'ReadFile' command [CMD]\n" + return writeGL_FAIL("GL Handle 'ReadFile' command [CMD]" +
" At offset: "+offset+"\n Requested: "+size+"\n Received: "+bytesRead); "\n At offset: " + offset +
"\n Requested: " + size +
"\n Received: " + bytesRead);
// Let's tell as a command about our result. // Let's tell as a command about our result.
if (writeGL_PASS(longToArrLE(size))) { if (writeGL_PASS(longToArrLE(size))) {
logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL);
@ -792,7 +815,7 @@ class GoldLeaf extends TransferModule {
} }
else { else {
randAccessFile.seek(offset); randAccessFile.seek(offset);
byte[] chunk = new byte[(int)size]; // WTF MAN? byte[] chunk = new byte[(int)size]; // yes, I know, but nothing to do here.
// Let's find out how much bytes we got // Let's find out how much bytes we got
int bytesRead = randAccessFile.read(chunk); int bytesRead = randAccessFile.read(chunk);
// Let's check that we read expected size // Let's check that we read expected size
@ -984,8 +1007,9 @@ class GoldLeaf extends TransferModule {
closeOpenedReadFilesGl(); // Could be a problem if GL glitches and slow down process. Or if user has extra-slow SD card. TODO: refactor closeOpenedReadFilesGl(); // Could be a problem if GL glitches and slow down process. Or if user has extra-slow SD card. TODO: refactor
continue; continue;
default: default:
logPrinter.print("GL Data transfer issue [read]\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); logPrinter.print("GL Data transfer issue [read]\n Returned: " +
logPrinter.print("GL Execution stopped", EMsgType.FAIL); UsbErrorCodes.getErrCode(result) +
"\n GL Execution stopped", EMsgType.FAIL);
return null; return null;
} }
} }
@ -1012,8 +1036,9 @@ class GoldLeaf extends TransferModule {
case LibUsb.ERROR_TIMEOUT: case LibUsb.ERROR_TIMEOUT:
continue; continue;
default: default:
logPrinter.print("GL Data transfer issue [read]\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL); logPrinter.print("GL Data transfer issue [read]\n Returned: " +
logPrinter.print("GL Execution stopped", EMsgType.FAIL); UsbErrorCodes.getErrCode(result) +
"\n GL Execution stopped", EMsgType.FAIL);
return null; return null;
} }
} }
@ -1067,110 +1092,21 @@ class GoldLeaf extends TransferModule {
if (writeBufTransferred.get() == message.length) if (writeBufTransferred.get() == message.length)
return false; return false;
else { else {
logPrinter.print("GL Data transfer issue [write]\n Requested: "+message.length+"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); logPrinter.print("GL Data transfer issue [write]\n Requested: " +
message.length +
"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL);
return true; return true;
} }
case LibUsb.ERROR_TIMEOUT: case LibUsb.ERROR_TIMEOUT:
continue; continue;
default: default:
logPrinter.print("GL Data transfer issue [write]\n Returned: "+ UsbErrorCodes.getErrCode(result), EMsgType.FAIL); logPrinter.print("GL Data transfer issue [write]\n Returned: " +
logPrinter.print("GL Execution stopped", EMsgType.FAIL); UsbErrorCodes.getErrCode(result) +
"\n GL Execution stopped", EMsgType.FAIL);
return true; return true;
} }
} }
logPrinter.print("GL Execution interrupted", EMsgType.INFO); logPrinter.print("GL Execution interrupted", EMsgType.INFO);
return true; return true;
} }
/*----------------------------------------------------*/
/* GL EXPERIMENTAL PART */
/* (left for better times) */
/*----------------------------------------------------*/
/*
private boolean proxyStatPath(String path) {
ByteBuffer writeBuffer = ByteBuffer.allocate(4096);
List<byte[]> fileBytesSize = new LinkedList<>();
if ((recentDirs.length == 0) && (recentFiles.length == 0)) {
return writeGL_FAIL("proxyStatPath");
}
if (recentDirs.length > 0){
writeBuffer.put(CMD_GLCO_SUCCESS);
writeBuffer.put(GL_OBJ_TYPE_DIR);
byte[] resultingDir = writeBuffer.array();
writeToUsb(resultingDir);
for (int i = 1; i < recentDirs.length; i++) {
readGL();
writeToUsb(resultingDir);
}
}
if (recentFiles.length > 0){
path = path.replaceAll(recentDirs[0]+"$", ""); // Remove the name from path
for (String fileName : recentFiles){
File f = new File(path+fileName);
fileBytesSize.add(longToArrLE(f.length()));
}
writeBuffer.clear();
for (int i = 0; i < recentFiles.length; i++){
readGL();
writeBuffer.clear();
writeBuffer.put(CMD_GLCO_SUCCESS);
writeBuffer.put(GL_OBJ_TYPE_FILE);
writeBuffer.put(fileBytesSize.get(i));
writeToUsb(writeBuffer.array());
}
}
return false;
}
private boolean proxyGetDirFile(boolean forDirs){
ByteBuffer writeBuffer = ByteBuffer.allocate(4096);
List<byte[]> dirBytesNameSize = new LinkedList<>();
List<byte[]> dirBytesName = new LinkedList<>();
if (forDirs) {
if (recentDirs.length <= 0)
return writeGL_FAIL("proxyGetDirFile");
for (String dirName : recentDirs) {
byte[] name = dirName.getBytes(StandardCharsets.UTF_16LE);
dirBytesNameSize.add(intToArrLE(name.length));
dirBytesName.add(name);
}
writeBuffer.put(CMD_GLCO_SUCCESS);
writeBuffer.put(dirBytesNameSize.get(0));
writeBuffer.put(dirBytesName.get(0));
writeToUsb(writeBuffer.array());
writeBuffer.clear();
for (int i = 1; i < recentDirs.length; i++){
readGL();
writeBuffer.put(CMD_GLCO_SUCCESS);
writeBuffer.put(dirBytesNameSize.get(i));
writeBuffer.put(dirBytesName.get(i));
writeToUsb(writeBuffer.array());
writeBuffer.clear();
}
}
else {
if (recentDirs.length <= 0)
return writeGL_FAIL("proxyGetDirFile");
for (String dirName : recentFiles){
byte[] name = dirName.getBytes(StandardCharsets.UTF_16LE);
dirBytesNameSize.add(intToArrLE(name.length));
dirBytesName.add(name);
}
writeBuffer.put(CMD_GLCO_SUCCESS);
writeBuffer.put(dirBytesNameSize.get(0));
writeBuffer.put(dirBytesName.get(0));
writeToUsb(writeBuffer.array());
writeBuffer.clear();
for (int i = 1; i < recentFiles.length; i++){
readGL();
writeBuffer.put(CMD_GLCO_SUCCESS);
writeBuffer.put(dirBytesNameSize.get(i));
writeBuffer.put(dirBytesName.get(i));
writeToUsb(writeBuffer.array());
writeBuffer.clear();
}
}
return false;
}
*/
} }

File diff suppressed because it is too large Load diff

View file

@ -52,12 +52,20 @@ public class UsbCommunications extends Task<Void> {
TransferModule module; TransferModule module;
if (protocol.equals("TinFoil")) switch (protocol) {
case "TinFoil":
module = new TinFoil(handler, nspMap, this, logPrinter); module = new TinFoil(handler, nspMap, this, logPrinter);
else if (protocol.equals("GoldLeaf")) break;
case "GoldLeaf":
module = new GoldLeaf(handler, nspMap, this, logPrinter, nspFilterForGl); module = new GoldLeaf(handler, nspMap, this, logPrinter, nspFilterForGl);
else break;
case "GoldLeafv0.7.x":
module = new GoldLeaf_07(handler, nspMap, this, logPrinter, nspFilterForGl);
break;
default:
module = new GoldLeaf_05(handler, nspMap, this, logPrinter); module = new GoldLeaf_05(handler, nspMap, this, logPrinter);
break;
}
usbConnect.close(); usbConnect.close();

View file

@ -69,7 +69,7 @@ public class SettingsController implements Initializable {
private HostServices hs; private HostServices hs;
private static final String[] oldGlSupportedVersions = {"v0.5"}; private static final String[] oldGlSupportedVersions = {"v0.5", "v0.7.x"};
@Override @Override
public void initialize(URL url, ResourceBundle resourceBundle) { public void initialize(URL url, ResourceBundle resourceBundle) {

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.9.1"; public static final String appVersion = "v1.0";
@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"));
@ -59,9 +59,8 @@ public class NSLMain extends Application {
} }
public static void main(String[] args) { public static void main(String[] args) {
if ((args.length == 1) && (args[0].equals("-v") || args[0].equals("--version"))){ if ((args.length == 1) && (args[0].equals("-v") || args[0].equals("--version")))
System.out.println("NS-USBloader "+NSLMain.appVersion); System.out.println("NS-USBloader "+NSLMain.appVersion);
}
else else
launch(args); launch(args);
} }