diff --git a/commands.js b/commands.js index f331d39..5361054 100644 --- a/commands.js +++ b/commands.js @@ -2,49 +2,61 @@ /* ---------------------Single commands--------------------- */ /* Create a directory */ - p7.commands.createDirectory = async (name, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.createDirectory, 0, 0, [name, '', '', '', fileSystem, '']); + p7.commands.createDirectory = async (name, filesystem) => await p7.send.singleCommand(flashCommandSubtype.createDirectory, 0, 0, [name, '', '', '', filesystem, '']); /* Delete a directory */ - p7.commands.deleteDirectory = async (name, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.deleteDirectory, 0, 0, [name, '', '', '', fileSystem, '']); + p7.commands.deleteDirectory = async (name, filesystem) => await p7.send.singleCommand(flashCommandSubtype.deleteDirectory, 0, 0, [name, '', '', '', filesystem, '']); /* Rename a directory */ - p7.commands.renameDirectory = async (oldName, newName, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.renameDirectory, 0, 0, [oldName, newName, '', '', fileSystem, '']); + p7.commands.renameDirectory = async (oldName, newName, filesystem) => await p7.send.singleCommand(flashCommandSubtype.renameDirectory, 0, 0, [oldName, newName, '', '', filesystem, '']); /* Change working directory */ - p7.commands.changeDirectory = async (name, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.changeDirectory, 0, 0, [name, '', '', '', fileSystem, '']); + p7.commands.changeDirectory = async (name, filesystem) => await p7.send.singleCommand(flashCommandSubtype.changeDirectory, 0, 0, [name, '', '', '', filesystem, '']); /* Delete a file */ - p7.commands.deleteFile = async (directory, name, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.deleteFile, 0, 0, [directory, name, '', '', fileSystem, '']); + p7.commands.deleteFile = async (directory, name, filesystem) => await p7.send.singleCommand(flashCommandSubtype.deleteFile, 0, 0, [directory, name, '', '', filesystem, '']); /* Rename a file */ - p7.commands.renameFile = async (directory, oldName, newName, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.renameFile, 0, 0, [directory, oldName, newName, '', fileSystem, '']); + p7.commands.renameFile = async (directory, oldName, newName, filesystem) => await p7.send.singleCommand(flashCommandSubtype.renameFile, 0, 0, [directory, oldName, newName, '', filesystem, '']); /* Copy a file */ - p7.commands.copyFile = async (oldDirectory, oldName, newDirectory, newName, fileSystem) => await p7.send.singleCommand(flashCommandSubtype.copyFile, 0, 0, [oldDirectory, oldName, newDirectory, newName, fileSystem, '']); + p7.commands.copyFile = async (oldDirectory, oldName, newDirectory, newName, filesystem) => await p7.send.singleCommand(flashCommandSubtype.copyFile, 0, 0, [oldDirectory, oldName, newDirectory, newName, filesystem, '']); - /* Optimize fileSystem */ - p7.commands.optimizeFileSystem = async (fileSystem) => await p7.send.singleCommand(flashCommandSubtype.optimizeFileSystem, 0, 0, ['', '', '', '', fileSystem, '']); + /* Reset flash? */ + p7.commands.resetFlash = async (filesystem) => await p7.send.singleCommand(flashCommandSubtype.resetFlash, 0, 0, ['', '', '', '', filesystem, '']); + + /* Optimize filesystem */ + p7.commands.optimizeFilesystem = async (filesystem) => await p7.send.singleCommand(flashCommandSubtype.optimizeFileSystem, 0, 0, ['', '', '', '', filesystem, '']); /* ---------------------Single command requests--------------------- */ - /* List files */ - p7.commands.list = async function (fileSystem) { - let fileList = []; - + /* Get free space */ + p7.commands.getCapacity = async function (filesystem) { try { - (await p7.send.singleCommandRoleswap(flashCommandSubtype.fileInfoTransferAllRequest, 0, 0, ['', '', '', '', fileSystem, ''])) - .forEach(element => - fileList.push({ - size: element.fileSize, - DirectoryName: element.data[0], - name: element.data[1] - }) - ); + return (await p7.send.singleCommandRoleswap(flashCommandSubtype.capacityTransmitRequest, 0, 0, ['', '', '', '', filesystem, ''], + () => p7.decode.commandPacketFileSize() + ))[0]; } catch (err) { - throw new Error("Couldn't list files: " + err.message); + err.message = "Couldn't get the size of the free space: " + err.message; + throw err; + } + } + + /* List files */ + p7.commands.list = async function (filesystem) { + try { + return await p7.send.singleCommandRoleswap(flashCommandSubtype.fileInfoTransferAllRequest, 0, 0, ['', '', '', '', filesystem, ''], + () => ({ + size: p7.decode.commandPacketFileSize(), + DirectoryName: p7.decode.commandPacketDataField(1), + name: p7.decode.commandPacketDataField(2) + }) + ); + } catch (err) { + err.message = "Couldn't list files: " + err.message; + throw err; } - - return fileList; } -}) (); \ No newline at end of file + +}) (); diff --git a/const.js b/const.js index 7396536..b664184 100644 --- a/const.js +++ b/const.js @@ -53,7 +53,7 @@ const flashCommandSubtype = { 'renameFile': 0x47, 'copyFile': 0x48, 'fileTransferAllRequest': 0x49, - 'unknownResetFlash': 0x4A, /* TODO: TEST*/ + 'resetFlash': 0x4A, 'capacityTransmitRequest': 0x4B, 'capacityTransmit': 0x4C, 'fileInfoTransferAllRequest': 0x4D, diff --git a/internal.js b/internal.js index 7edc07d..0fa1dc1 100644 --- a/internal.js +++ b/internal.js @@ -188,99 +188,93 @@ var p7 = { let dataFieldSize = []; let index = 20 while(index < 32) - dataFieldSize.push(p7.receiveBuffer.slice(index, (index += 2)).asciiToHex()); + dataFieldSize.push(p7.receiveBuffer.subarray(index, (index += 2)).asciiToHex()); - let dataField = []; - dataFieldSize.forEach((element) => dataField.push(p7.receiveBuffer.slice(index, (index += element)).asciiToString())); - return dataField; + return dataFieldSize.map((element) => p7.receiveBuffer.slice(index, (index += element)).asciiToString()); } /* ---------------------Packet receiving--------------------- */ - p7.receive.packet = async function () { + p7.receive.packet = function () { console.log("%cReceiving...", "color: orange"); - let transferInResult = undefined; - - try { - while (! (transferInResult = await p7.device.transferIn(2, 64)).data.byteLength) - console.log('The buffer was empty, trying again!'); - - p7.receiveBuffer.set(new Uint8Array(transferInResult.data.buffer), 0); - } catch (err) { - throw new Error("Couldn't receive the first 64 bytes of the packet: " + err.message); - } - - let packetInfo = {} - packetInfo.length = 6; /* Type (T), Subtype (S), Extended (EX) and Checksum (CS) fields */ - - //Set Type (T) field - packetInfo.type = p7.receiveBuffer[0]; - - //Set Subtype (ST) field - packetInfo.subtype = p7.receiveBuffer.slice(1, 2).asciiToHex(); - - //Set Extended (EX) field - packetInfo.extended = (p7.receiveBuffer[3] === 0x31); - - if (packetInfo.extended) { - //Set Data size (DS) field - packetInfo.dataSize = p7.receiveBuffer.slice(4, 8).asciiToHex(); - - packetInfo.length += packetInfo.dataSize + 4 /* Data size field */; - - for (let transfered = 64 ; transfered < packetInfo.length ; transfered += 64) { - try { - transferInResult = await p7.device.transferIn(2, 64); - } catch (err) { - throw new Error("Couldn't receive the " + transfered + "th and following 64 bytes of the packet: " + err.message) + + var packetInfo = {} + var transfered = 0; + + return p7.device.transferIn(2, 64) + .then(function receive(transferInResult) { + if (!transferInResult.data.byteLength) { + console.log('The buffer was empty, trying again!'); + return p7.device.transferIn(2, 64).then(receive); } + + p7.receiveBuffer.set(new Uint8Array(transferInResult.data.buffer), 0); + + packetInfo.length = 6; //Type (T), Subtype (S), Extended (EX) and Checksum (CS) fields + + //Set Type (T) field + packetInfo.type = p7.receiveBuffer[0]; + + //Set Subtype (ST) field + packetInfo.subtype = p7.receiveBuffer.slice(1, 2).asciiToHex(); - p7.receiveBuffer.set(new Uint8Array(transferInResult.data.buffer), transfered); - } - } + //Set Extended (EX) field + packetInfo.extended = (p7.receiveBuffer[3] === 0x31); + }).then(() => { + if (packetInfo.extended) { + console.log('Packet is extended, receiving...'); - /* Compute checksum */ - let checksumError = ((packetInfo.checksum = p7.receiveBuffer.slice(packetInfo.length - 2, packetInfo.length).asciiToHex()) !== p7.receiveBuffer.slice(1, packetInfo.length - 2).p7Checksum()); + //Set Data size (DS) field + packetInfo.dataSize = p7.receiveBuffer.slice(4, 8).asciiToHex(); + + packetInfo.length += packetInfo.dataSize + 4; //Data size field + + var transfered = 64; - if (checksumError && (checksumTries++) < 3) { - console.log('there was a checksum error'); - try { - packetInfo = await p7.send.basicPacket(p7PacketType.error, errorSubtype.resendRequest); - } catch (err) { - throw new Error("Couldn't send the resend request: " + err.message); + return p7.device.transferIn(2, 64) + .then(function receiveRemainingPackets(transferInResult) { + p7.receiveBuffer.set(new Uint8Array(transferInResult.data.buffer), transfered); + + if ((transfered += 64) < packetInfo.length) + return p7.device.transferIn(2, 64).then(receiveRemainingPackets); + }) } - } - if (checksumTries === 4) { - checksumTries = 0; - throw new Error("There were three checksum in a row, the calculator or the cable may be broken!"); - } - - return packetInfo; + }).then(() => { + //Compute checksum + let checksumError = ((packetInfo.checksum = p7.receiveBuffer.slice(packetInfo.length - 2, packetInfo.length).asciiToHex()) !== p7.receiveBuffer.slice(1, packetInfo.length - 2).p7Checksum()); + + console.log(checksumError); + return packetInfo; + }).catch((err) => { + err.message = "Couldn't receive the " + transfered + " to " + (transfered + 64) + " bytes of the packet: " + err.message; + throw err; + }); } + /* ---------------------Packet sending--------------------- */ p7.send.packet = async function (length) { let responsePacketInfo = undefined; let tries = 0; console.log("%cSending packet...", "color: green"); - for ( ; tries === 0 || (responsePacketInfo.type === p7PacketType.error && responsePacketInfo.subtype === errorSubtype.resendRequest && tries < 3) ; tries++) { - try { - await p7.device.transferOut(1, p7.sendBuffer.slice(0, length)); - } catch (err) { - throw new Error("Couldn't send the packet: " + err.message); - } - try { - responsePacketInfo = await p7.receive.packet(); - } catch (err) { - throw new Error("Couldn't receive the response packet: " + err.message); - } + try { + await p7.device.transferOut(1, p7.sendBuffer.slice(0, length)); + } catch (err) { + err.message = "Couldn't send the packet: " + err.message; + throw err; + } + try { + responsePacketInfo = await p7.receive.packet(); + } catch (err) { + err.message = "Couldn't receive the response packet: " + err.message; + throw err; } - if (tries === 3) - throw new Error("Received three resend request in a row, abandon"); - return responsePacketInfo; - }; + } + + + p7.send.basicPacket = async (type, subtype) => await p7.send.packet(p7.make.basicPacket(type, subtype)); @@ -303,9 +297,9 @@ var p7 = { /* Send a single command request * Return the Data (D) field of the response command packet(s) */ - p7.send.singleCommandRoleswap = async function (subtype, datatype, fileSize, commandArguments) { + p7.send.singleCommandRoleswap = async function (subtype, datatype, fileSize, commandArguments, callbackFunction) { /* Array to store the Data (D) field of the response command packet(s) */ - let requestedCommandResult = []; + let result = []; /* Send the command */ let responsePacketInfo = await p7.send.extendedCommandPacket(subtype, datatype, fileSize, commandArguments); @@ -317,19 +311,15 @@ var p7 = { /* Receive all the requested command packets and store their Data (D) field */ while (responsePacketInfo.type === p7PacketType.command) { - requestedCommandResult.push({ - overwrite: p7.decode.commandPacketOverWrite(), - datatype: p7.decode.commandPacketDataType(), - fileSize: p7.decode.commandPacketFileSize(), - data: p7.decode.commandPacketAllDataFields() - }) + result.push(callbackFunction()); responsePacketInfo = await p7.send.basicPacket(p7PacketType.ack, ackSubtype.default); } /* Everything went right */ - return requestedCommandResult; + return result; } + /* ---------------------Initialization and exiting--------------------- */ @@ -341,7 +331,7 @@ var p7 = { {'vendorId': 0x07cf , 'productId': 0x6102}] /* fx-CP400 */ }); } catch (err) { - throw new Error("Couldn't find the calculator: " + err.message); + throw new Error("Couldn't find the calculator"); } await p7.device.open(); @@ -354,6 +344,9 @@ var p7 = { console.log(p7.device); + /* Everything went right */ + return 0; + /* Receive and send some usb control message, as defined in fxReverse documentation * * Adapted version (some parameters changed since fxReverse's writing) of usb_control_msg() function's protoype @@ -452,10 +445,7 @@ var p7 = { }, controlData); } catch (err) { console.log(err); - } */ - - /* Everything went right */ - return 0; + } */ } /* End the connexion with the calculator */ @@ -467,23 +457,23 @@ var p7 = { document.getElementById('connect').addEventListener('click', async function () { - try { - await p7.init(); + try { + await p7.init(); - await p7.send.basicPacket(p7PacketType.check, checkSubtype.initialization); + await p7.send.basicPacket(p7PacketType.check, checkSubtype.initialization); - await p7.send.basicPacket(p7PacketType.command, sysCommandSubtype.getDeviceInfo); + await p7.send.basicPacket(p7PacketType.command, sysCommandSubtype.getDeviceInfo); - } catch (err) { + } catch (err) { console.error(err); return err; - } + } console.log(p7.decode.extendedAckPacket()); console.log(await p7.commands.list('fls0')); - + console.log(await p7.commands.createDirectory('test', 'fls0')); console.log(await p7.commands.list('fls0'));