Fully asynchronous internal commands
This commit is contained in:
parent
f32643c13a
commit
a64295504d
53
commands.js
53
commands.js
|
@ -2,61 +2,54 @@
|
|||
/* ---------------------Single commands--------------------- */
|
||||
|
||||
/* Create a directory */
|
||||
p7.commands.createDirectory = async (name, filesystem) => await p7.send.singleCommand(flashCommandSubtype.createDirectory, 0, 0, [name, '', '', '', filesystem, '']);
|
||||
p7.commands.createDirectory = (name, filesystem) => 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 = (name, filesystem) => 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 = (oldName, newName, filesystem) => 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 = (name, filesystem) => 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 = (directory, name, filesystem) => 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 = (directory, oldName, newName, filesystem) => 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 = (oldDirectory, oldName, newDirectory, newName, filesystem) => p7.send.singleCommand(flashCommandSubtype.copyFile, 0, 0, [oldDirectory, oldName, newDirectory, newName, filesystem, '']);
|
||||
|
||||
/* Reset flash? */
|
||||
p7.commands.resetFlash = async (filesystem) => await p7.send.singleCommand(flashCommandSubtype.resetFlash, 0, 0, ['', '', '', '', filesystem, '']);
|
||||
p7.commands.resetFlash = (filesystem) => p7.send.singleCommand(flashCommandSubtype.resetFlash, 0, 0, ['', '', '', '', filesystem, '']);
|
||||
|
||||
/* Optimize filesystem */
|
||||
p7.commands.optimizeFilesystem = async (filesystem) => await p7.send.singleCommand(flashCommandSubtype.optimizeFileSystem, 0, 0, ['', '', '', '', filesystem, '']);
|
||||
p7.commands.optimizeFilesystem = (filesystem) => p7.send.singleCommand(flashCommandSubtype.optimizeFileSystem, 0, 0, ['', '', '', '', filesystem, '']);
|
||||
|
||||
/* ---------------------Single command requests--------------------- */
|
||||
|
||||
/* Get free space */
|
||||
p7.commands.getCapacity = async function (filesystem) {
|
||||
try {
|
||||
return (await p7.send.singleCommandRoleswap(flashCommandSubtype.capacityTransmitRequest, 0, 0, ['', '', '', '', filesystem, ''],
|
||||
() => p7.decode.commandPacketFileSize()
|
||||
))[0];
|
||||
} catch (err) {
|
||||
p7.commands.getCapacity = (filesystem) =>
|
||||
p7.send.singleCommandRoleswap(flashCommandSubtype.capacityTransmitRequest, 0, 0, ['', '', '', '', filesystem, ''],
|
||||
() => p7.decode.commandPacketFileSize()
|
||||
).then((filteredData) => filteredData[0])
|
||||
.catch((err) => {
|
||||
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) {
|
||||
p7.commands.list = (filesystem) =>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}) ();
|
||||
|
|
343
internal.js
343
internal.js
|
@ -200,211 +200,202 @@ var p7 = {
|
|||
|
||||
/* ---------------------Packet sending--------------------- */
|
||||
|
||||
p7.send.packet = async function (buffer) {
|
||||
p7.send.packet = function (buffer) {
|
||||
console.log("%cSending packet...", "color: green");
|
||||
return p7.device.transferOut(1, Uint8Array.from(buffer))
|
||||
.then(() => p7.receive.packet());
|
||||
.catch((err) => {
|
||||
err.message = "Couldn't send the packet: " + err.message;
|
||||
throw err;
|
||||
})
|
||||
.then(() => p7.receive.packet())
|
||||
.catch((err) => {
|
||||
err.message = "Couldn't receive the response packet: " + err.message;
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
p7.send.basicPacket = async (type, subtype) => await p7.send.packet(p7.make.basicPacket(type, subtype));
|
||||
|
||||
p7.send.extendedCommandPacket = async (subtype, datatype, fileSize, commandArguments) => await p7.send.packet(p7.make.extendedCommandPacket(subtype, datatype, fileSize, commandArguments));
|
||||
|
||||
p7.send.dataPacket = async (subtype, totalNumber, currentNumber, data) => await p7.send.packet(p7.make.dataPacket(subtype, totalNumber, currentNumber, data));
|
||||
|
||||
/* Send a single command
|
||||
* Return the informations about the response ack packet */
|
||||
p7.send.singleCommand = async function (subtype, datatype, fileSize, commandArguments) {
|
||||
/* Send the command */
|
||||
let responsePacketInfo = await p7.send.extendedCommandPacket(subtype, datatype, fileSize, commandArguments);
|
||||
|
||||
/* Check if the packet is an ack packet */
|
||||
if (!(responsePacketInfo.type === p7PacketType.ack && responsePacketInfo.subtype === ackSubtype.default))
|
||||
throw new Error("The calculator didn't send the expected ack packet !");
|
||||
|
||||
return responsePacketInfo;
|
||||
}
|
||||
p7.send.singleCommand = (subtype, datatype, fileSize, commandArguments) =>
|
||||
p7.send.packet(p7.make.extendedCommandPacket(subtype, datatype, fileSize, commandArguments))
|
||||
.then((responsePacketInfo) => {
|
||||
//Check if the packet is an ack packet
|
||||
if (!(responsePacketInfo.type === p7PacketType.ack && responsePacketInfo.subtype === ackSubtype.default))
|
||||
throw new Error("The calculator didn't send the expected ack packet!");
|
||||
});
|
||||
|
||||
/* 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, callbackFunction) {
|
||||
/* Array to store the Data (D) field of the response command packet(s) */
|
||||
let result = [];
|
||||
* Return an array containing the filtered (with `callbackFunction`) Data (D) field of each response command packet */
|
||||
p7.send.singleCommandRoleswap = function (subtype, datatype, fileSize, commandArguments, callbackFunction) {
|
||||
var filteredData = [];
|
||||
|
||||
/* Send the command */
|
||||
let responsePacketInfo = await p7.send.extendedCommandPacket(subtype, datatype, fileSize, commandArguments);
|
||||
if (!(responsePacketInfo.type === p7PacketType.ack && responsePacketInfo.subtype === ackSubtype.default))
|
||||
throw new Error("The calculator didn't send the expected ack packet !");
|
||||
|
||||
/* Exchange roles */
|
||||
responsePacketInfo = await p7.send.basicPacket(p7PacketType.roleswap, roleswapSubtype.default);
|
||||
|
||||
/* Receive all the requested command packets and store their Data (D) field */
|
||||
while (responsePacketInfo.type === p7PacketType.command) {
|
||||
result.push(callbackFunction());
|
||||
responsePacketInfo = await p7.send.basicPacket(p7PacketType.ack, ackSubtype.default);
|
||||
}
|
||||
|
||||
/* Everything went right */
|
||||
return result;
|
||||
return p7.send.singleCommand(subtype, datatype, fileSize, commandArguments)
|
||||
.then((responsePacketInfo) => p7.send.packet(p7.make.basicPacket(p7PacketType.roleswap, roleswapSubtype.default)))
|
||||
.then(function receiveRequestedCommand(responsePacketInfo) {
|
||||
if (responsePacketInfo.type !== p7PacketType.command)
|
||||
return filteredData;
|
||||
|
||||
filteredData.push(callbackFunction());
|
||||
return p7.send.packet(p7.make.basicPacket(p7PacketType.ack, ackSubtype.default)).then(receiveRequestedCommand);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---------------------Initialization and exiting--------------------- */
|
||||
|
||||
/* Initiate the connexion with the calculator */
|
||||
p7.init = async function () {
|
||||
try {
|
||||
p7.device = await navigator.usb.requestDevice({filters:[
|
||||
{'vendorId': 0x07cf , 'productId': 0x6101}, /* fx-9750gII */
|
||||
{'vendorId': 0x07cf , 'productId': 0x6102}] /* fx-CP400 */
|
||||
});
|
||||
} catch (err) {
|
||||
throw new Error("Couldn't find the calculator");
|
||||
}
|
||||
/* Connect to the calculator */
|
||||
p7.connect = () =>
|
||||
navigator.usb.requestDevice({filters:[
|
||||
{'vendorId': 0x07cf , 'productId': 0x6101}, //fx-9750gII
|
||||
{'vendorId': 0x07cf , 'productId': 0x6102}] //fx-CP400
|
||||
}).then((device) => {
|
||||
p7.device = device
|
||||
return p7.device.open();
|
||||
}).then(() => {
|
||||
if (p7.device.configuration === null)
|
||||
return p7.device.selectConfiguration(1); //Only existing one so it should be selected by default, just checking
|
||||
}).then(() => {
|
||||
if (p7.device.configuration.interfaces[0].claimed === false)
|
||||
return p7.device.claimInterface(0); //Same as for the configuration
|
||||
});
|
||||
|
||||
/* 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
|
||||
* from linux-manual : https://manpages.debian.org/jessie-backports/linux-manual-4.8/usb_control_msg.9.en.html
|
||||
*
|
||||
* int usb_control_msg(struct usb_device * dev,
|
||||
* uint8_t requesttype,
|
||||
* uint8_t request,
|
||||
* uint16_t value,
|
||||
* uint16_t index,
|
||||
* void * data,
|
||||
* uint16_t size,
|
||||
* int timeout);
|
||||
*
|
||||
* fxReverse2:13:
|
||||
*
|
||||
* int init_connection() {
|
||||
* char *buffer = calloc(0x29, sizeof(char));
|
||||
*
|
||||
* //Receive 0x12 bytes of data
|
||||
* usb_control_message(usb_handle,
|
||||
* 0x80, = 0b10000000
|
||||
* - D7 = 1 -> Data transfer direction: Device-to-host
|
||||
* - D6...D5 = 0 -> Type: Standard
|
||||
* - D4...D0 = 0 -> Recipient: Device
|
||||
* 0x6,
|
||||
* 0x0100,
|
||||
* 0x0,
|
||||
* buffer,
|
||||
* 0x12,
|
||||
* 200);
|
||||
*
|
||||
* //Same arguments (except timeout), but value is 0x200 and it receives 0x29 bytes of data
|
||||
* usb_control_message(usb_handle, 0x80, 0x6, 0x200, 0, buffer, 0x29, 250);
|
||||
*
|
||||
*
|
||||
* usb_control_message(usb_handle,
|
||||
* 0x41, = 0b01000001
|
||||
* - D7 = 0 -> Data transfer direction: Host-to-device
|
||||
* - D6...D5 = 2 -> Type: Vendor
|
||||
* - D4...D0 = 1 -> Interface: Interface
|
||||
* 0x1,
|
||||
* 0x0,
|
||||
* 0,
|
||||
* buffer,
|
||||
* 0x0,
|
||||
* 250);
|
||||
*
|
||||
* free(buffer);
|
||||
* return 0;
|
||||
* }
|
||||
****************************************************************
|
||||
|
||||
await p7.device.open();
|
||||
|
||||
if (p7.device.configuration === null)
|
||||
await p7.device.selectConfiguration(1); /* Only existing one so it should be selected by default, just checking */
|
||||
|
||||
if (p7.device.configuration.interfaces[0].claimed === false)
|
||||
await p7.device.claimInterface(0); /* Same as for the configuration */
|
||||
let transferInResult = undefined;
|
||||
let controlData = undefined;
|
||||
|
||||
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
|
||||
* from linux-manual : https://manpages.debian.org/jessie-backports/linux-manual-4.8/usb_control_msg.9.en.html
|
||||
*
|
||||
* int usb_control_msg(struct usb_device * dev,
|
||||
* uint8_t requesttype,
|
||||
* uint8_t request,
|
||||
* uint16_t value,
|
||||
* uint16_t index,
|
||||
* void * data,
|
||||
* uint16_t size,
|
||||
* int timeout);
|
||||
*
|
||||
* fxReverse2:13:
|
||||
*
|
||||
* int init_connection() {
|
||||
* char *buffer = calloc(0x29, sizeof(char));
|
||||
*
|
||||
* //Receive 0x12 bytes of data
|
||||
* usb_control_message(usb_handle,
|
||||
* 0x80, = 0b10000000
|
||||
* - D7 = 1 -> Data transfer direction: Device-to-host
|
||||
* - D6...D5 = 0 -> Type: Standard
|
||||
* - D4...D0 = 0 -> Recipient: Device
|
||||
* 0x6,
|
||||
* 0x0100,
|
||||
* 0x0,
|
||||
* buffer,
|
||||
* 0x12,
|
||||
* 200);
|
||||
*
|
||||
* //Same arguments (except timeout), but value is 0x200 and it receives 0x29 bytes of data
|
||||
* usb_control_message(usb_handle, 0x80, 0x6, 0x200, 0, buffer, 0x29, 250);
|
||||
*
|
||||
*
|
||||
* usb_control_message(usb_handle,
|
||||
* 0x41, = 0b01000001
|
||||
* - D7 = 0 -> Data transfer direction: Host-to-device
|
||||
* - D6...D5 = 2 -> Type: Vendor
|
||||
* - D4...D0 = 1 -> Interface: Interface
|
||||
* 0x1,
|
||||
* 0x0,
|
||||
* 0,
|
||||
* buffer,
|
||||
* 0x0,
|
||||
* 250);
|
||||
*
|
||||
* free(buffer);
|
||||
* return 0;
|
||||
* }
|
||||
****************************************************************
|
||||
|
||||
let transferInResult = undefined;
|
||||
let controlData = undefined;
|
||||
|
||||
try {
|
||||
transferInResult = await p7.device.controlTransferIn({
|
||||
requestType: 'standard',
|
||||
recipient: 'device',
|
||||
request: 0x06, // GET_DESCRIPTOR
|
||||
value: 0x0100, // Descriptor Type and Descriptor Index
|
||||
index: 0x0000
|
||||
}, 0x12); // Length
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
controlData = new Uint8Array(transferInResult.data.buffer);
|
||||
|
||||
console.log('vendor id : 0x' + controlData[9].toString(16).padStart(2, 0) + controlData[8].toString(16).padStart(2,0));
|
||||
console.log('product id : 0x' + controlData[11].toString(16).padStart(2, 0) + controlData[10].toString(16).padStart(2,0));
|
||||
|
||||
try {
|
||||
try {
|
||||
transferInResult = await p7.device.controlTransferIn({
|
||||
requestType: 'standard',
|
||||
recipient: 'device',
|
||||
request: 0x06, // GET_DESCRIPTOR
|
||||
value: 0x0200, // Descriptor Type and Descriptor Index
|
||||
index: 0x0000
|
||||
}, 0x29); // Length
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
controlData = new Uint8Array(transferInResult.data.buffer);
|
||||
console.log(controlData);
|
||||
|
||||
try {
|
||||
await p7.device.controlTransferOut({
|
||||
requestType: 'vendor',
|
||||
recipient: 'interface',
|
||||
request: 0x01,
|
||||
value: 0x0000,
|
||||
index: 0x0000
|
||||
}, controlData);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} */
|
||||
requestType: 'standard',
|
||||
recipient: 'device',
|
||||
request: 0x06, // GET_DESCRIPTOR
|
||||
value: 0x0100, // Descriptor Type and Descriptor Index
|
||||
index: 0x0000
|
||||
}, 0x12); // Length
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
controlData = new Uint8Array(transferInResult.data.buffer);
|
||||
|
||||
console.log('vendor id : 0x' + controlData[9].toString(16).padStart(2, 0) + controlData[8].toString(16).padStart(2,0));
|
||||
console.log('product id : 0x' + controlData[11].toString(16).padStart(2, 0) + controlData[10].toString(16).padStart(2,0));
|
||||
|
||||
try {
|
||||
transferInResult = await p7.device.controlTransferIn({
|
||||
requestType: 'standard',
|
||||
recipient: 'device',
|
||||
request: 0x06, // GET_DESCRIPTOR
|
||||
value: 0x0200, // Descriptor Type and Descriptor Index
|
||||
index: 0x0000
|
||||
}, 0x29); // Length
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
controlData = new Uint8Array(transferInResult.data.buffer);
|
||||
console.log(controlData);
|
||||
|
||||
try {
|
||||
await p7.device.controlTransferOut({
|
||||
requestType: 'vendor',
|
||||
recipient: 'interface',
|
||||
request: 0x01,
|
||||
value: 0x0000,
|
||||
index: 0x0000
|
||||
}, controlData);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} */
|
||||
|
||||
/* Initialize the connection with the calculator */
|
||||
p7.init = () =>
|
||||
p7.connect()
|
||||
.catch(() => {
|
||||
throw new Error("Couldn't connect to the calculator!");
|
||||
}).then(() => p7.send.packet(p7.make.basicPacket(p7PacketType.check, checkSubtype.initialization))
|
||||
.catch(() => {
|
||||
throw new Error("Couldn't send the initialisation packet!");
|
||||
}).then(() => p7.send.packet(p7.make.basicPacket(p7PacketType.command, sysCommandSubtype.getDeviceInfo))
|
||||
.catch(() => {
|
||||
throw new Error("Couldn't ask for the device infos!");
|
||||
}).then(() => p7.decode.extendedAckPacket())));
|
||||
|
||||
/* End the connexion with the calculator */
|
||||
p7.exit = async function () {
|
||||
p7.exit = async function () {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
document.getElementById('connect').addEventListener('click',
|
||||
async function () {
|
||||
var time = performance.now();
|
||||
try {
|
||||
await p7.init();
|
||||
|
||||
await p7.send.basicPacket(p7PacketType.check, checkSubtype.initialization);
|
||||
|
||||
await p7.send.basicPacket(p7PacketType.command, sysCommandSubtype.getDeviceInfo);
|
||||
|
||||
} catch (err) {
|
||||
return p7.init()
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
return err;
|
||||
}
|
||||
}).then((deviceInfo) => {
|
||||
console.log(deviceInfo);
|
||||
|
||||
console.log(p7.decode.extendedAckPacket());
|
||||
//Main commands
|
||||
p7.commands.list('fls0')
|
||||
.then((fileList) => console.log('The following files are in the flash memory: %o', fileList))
|
||||
.then(() => p7.commands.getCapacity('fls0'))
|
||||
.then((capacity) => console.log('Flash memory free space: ' + capacity + 'o'))
|
||||
.then(() => console.log('Done. (in ' + Math.round(performance.now() - time) + 'ms)'));
|
||||
})
|
||||
|
||||
|
||||
console.log(await p7.commands.list('fls0'));
|
||||
|
||||
console.log(performance.now() - time);
|
||||
});
|
||||
})();
|
||||
|
||||
})();
|
||||
|
|
Loading…
Reference in New Issue