remake of internal functions
This commit is contained in:
parent
a18984ad97
commit
859967d013
25
README.md
25
README.md
|
@ -1,3 +1,26 @@
|
|||
#Usage
|
||||
# Warning : Use this tool at your own risks, nobody can be taken as responsible if it damage your calculator !!!
|
||||
|
||||
|
||||
# Usage
|
||||
The buttons are actually diconnected, if you want to test, dive through the code.
|
||||
|
||||
# Things to change
|
||||
- Have a more js-like code approach !
|
||||
|
||||
# Actual possibilities
|
||||
- You can send files to flash memory (at least fls0, but maybe crd0 too), but only below ~1.5 ko (it freezes beyond, will patch this later)
|
||||
- You can list files, make directories, remove directories etc...
|
||||
- you can optimize your flash
|
||||
- you can get your device infos
|
||||
|
||||
# Future possibilities
|
||||
|
||||
- Make a user friendly interface
|
||||
- Support all p7 protocol's commands
|
||||
- Screen casting ? (not a usb but a graphic difficulty)
|
||||
- other stuffs
|
||||
|
||||
# Thanks to :
|
||||
|
||||
Simon Lothar for his fx-reverse doc
|
||||
Cakeisalie5 for his p7 command line tool
|
239
index.js
239
index.js
|
@ -1,233 +1,14 @@
|
|||
"use strict";
|
||||
let device = undefined;
|
||||
let fileList = undefined;
|
||||
|
||||
|
||||
let p7SendBuffer = new Uint8Array(1032); //Max send buffer size
|
||||
let p7ReceiveBuffer = new Uint8Array(1032 + 1); //Max receive buffer size
|
||||
|
||||
let p7ReceivedPacketInfo = {
|
||||
'type' : undefined,
|
||||
'subtype' : undefined,
|
||||
'extended' : undefined,
|
||||
'dataSize' : undefined,
|
||||
'data' : undefined,
|
||||
'checksum' : undefined,
|
||||
'packetSize': undefined
|
||||
};
|
||||
|
||||
|
||||
let p7DeviceInformation = {
|
||||
'hardwareIdentifier' : undefined,
|
||||
'processorIdentifier' : undefined,
|
||||
'preprogrammedROMCapacity' : undefined,
|
||||
'flashROMCapacity' : undefined,
|
||||
'ramCapacity' : undefined,
|
||||
'prepogrammedROMVersion' : undefined,
|
||||
'bootCodeVersion' : undefined,
|
||||
'bootCodeOffset' : undefined,
|
||||
'bootCodeSize' : undefined,
|
||||
'osCodeVersion' : undefined,
|
||||
'osCodeOffset' : undefined,
|
||||
'osCodeSize' : undefined,
|
||||
'protocolVersion' : undefined,
|
||||
'productID' : undefined,
|
||||
'nameSetByUserInSystem' : undefined
|
||||
};
|
||||
|
||||
var fls0 = [];
|
||||
var crd0 = [];
|
||||
|
||||
/* List the files of a filesystem (fls0, crd0...) */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function list(fileSystem) {
|
||||
let err = 0;
|
||||
|
||||
//Send a command packet requesting the calculator to list it's file (in the flash memory) and receive the response packet
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.fileInfoTransferAllRequest, 0, 0, 0, ["", "", "", "", fileSystem, ""]))
|
||||
return "Couldn't send the command packet to the calculator : " + err;
|
||||
|
||||
//Send a roleswap packet so that the calculator can become the active side and send the list of it's files (in flash memory)
|
||||
if (err = await p7SendBasicPacket(p7PacketType.roleswap, roleswapSubtype.default))
|
||||
return "Couldn't send the roleswap packet : " + err;
|
||||
|
||||
//Reset the list since the calculator send each time all it's elements
|
||||
window[fileSystem] = [];
|
||||
|
||||
//Receive and parse the file list
|
||||
while(p7ReceivedPacketInfo.type !== p7PacketType.roleswap) {
|
||||
window[fileSystem].push(createFileObject(String.fromCharCode.apply(null, p7CommandPacketGetField(4)), String.fromCharCode.apply(null, p7CommandPacketGetField(0)), String.fromCharCode.apply(null, p7CommandPacketGetField(1)), p7CommandPacketGetFilesize()));
|
||||
|
||||
if (err = await p7SendBasicPacket(p7PacketType.ack, ackSubtype.default))
|
||||
return "Couldn't send the acknowledgement packet : " + err;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
async function createDirectory(name, filesystem) {
|
||||
let err = 0;
|
||||
//Send a command packet which asks the calculator to create a directory
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.createDirectory, 0, 0, 0, [name, "", "", "", filesystem, ""]))
|
||||
return 'Couldn\'t send the command : ' + err;
|
||||
|
||||
//Check the response packet type
|
||||
if (p7ReceivedPacketInfo.type === p7PacketType.ack)
|
||||
return 0;
|
||||
return "The response packet wasn't as expected.";
|
||||
}
|
||||
|
||||
async function deleteDirectory(name, filesystem) {
|
||||
let err = 0;
|
||||
//Send a command packet which asks the calculator to delete a directory
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.deleteDirectory, 0, 0, 0, [name, "", "", "", filesystem, ""]))
|
||||
return 'Couldn\'t send the command : ' + err;
|
||||
|
||||
//Check the response packet type
|
||||
if (p7ReceivedPacketInfo.type === p7PacketType.ack)
|
||||
return 0;
|
||||
return "The response packet wasn't as expected.";
|
||||
}
|
||||
|
||||
/* Doesn't work ?? */
|
||||
async function renameDirectory(oldName, newName, filesystem) {
|
||||
let err = 0;
|
||||
//Send a command packet which asks the calculator to delete a directory
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.renameDirectory, 0, 0, 0, [oldName, newName, "", "", filesystem, ""]))
|
||||
return 'Couldn\'t send the command : ' + err;
|
||||
|
||||
//check the response packet type
|
||||
if (p7ReceivedPacketInfo.type === p7PacketType.ack)
|
||||
return 0;
|
||||
return "The response packet wasn't as expected.";
|
||||
}
|
||||
|
||||
/* Doesn't work ?? */
|
||||
async function changeDirectory(name, filesystem) {
|
||||
let err = 0;
|
||||
//Send a command packet which asks the calculator change working directory
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.changeDirectory, 0, 0, 0, [name, "", "", "", filesystem, ""]))
|
||||
return 'Couldn\'t send the command : ' + err;
|
||||
|
||||
if (p7ReceivedPacketInfo.type === p7PacketType.ack)
|
||||
return 0;
|
||||
return "The response packet wasn't as expected.";
|
||||
}
|
||||
|
||||
/* TODO: finish it */
|
||||
async function fileTransfer(file, path, fileSystem) {
|
||||
let err = 0;
|
||||
console.log('Sending file transfer request');
|
||||
//Send a command packet which asks the calculator if we can send a file
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.fileTransfer, 0, 0, file.size, [path, file.name, "", "", fileSystem, ""]))
|
||||
return 'Couldn\'t send the command : ' + err;
|
||||
|
||||
console.log(p7SendBuffer.slice(0, 64));
|
||||
if (p7ReceivedPacketInfo.type === p7PacketType.error && p7ReceivedPacketInfo.subtype === errorSubtype.overwriteRequest) {
|
||||
if (err = (confirm('The file already exists, overwrite ?')) ? await p7SendBasicPacket(p7PacketType.ack, ackSubtype.overwriteYes) : await p7SendBasicPacket(p7PacketType.error, errorSubtype.overwriteNo))
|
||||
return 'Couldn\'t send the overwrite response packet : ' + err;
|
||||
if (p7ReceivedPacketInfo.type === p7PacketType.error && p7ReceivedPacketInfo.subtype === errorSubtype.overwriteImpossible)
|
||||
return 'The calculator couldn\'t overwrite the file : ' + err;
|
||||
}
|
||||
|
||||
console.log('Sending data');
|
||||
if (err = await p7SendData(flashCommandSubtype.fileTransfer, content))
|
||||
return 'Couldn\'t send the file : ' + err;
|
||||
|
||||
if (p7ReceivedPacketInfo.type ==! p7PacketType.ack)
|
||||
return "unexpected response packet";
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: add promise system */
|
||||
function getCapacity(fileSystem) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let err = 0;
|
||||
//Send a command packet requesting the calculator to send it's capacity (free memory)
|
||||
if (err = p7SendExtendedCommandPacket(flashCommandSubtype.capacityTransmitRequest, 0, 0, 0, ["", "", "", "", fileSystem, ""]))
|
||||
reject('Couldn\'t send the command packet to the calculator : ' + err);
|
||||
|
||||
//Send a roleswap packet so that the calculator can become the active side and send it's capacity
|
||||
if (err = p7SendBasicPacket(p7PacketType.roleswap, roleswapSubtype.default))
|
||||
reject('Couldn\'t send the roleswap packet : ' + err);
|
||||
|
||||
let freeMemory = p7CommandPacketGetFilesize();
|
||||
|
||||
//Send an acknowledgement packet and receive the response packet
|
||||
if (err = p7SendBasicPacket(p7PacketType.ack, roleswapSubtype.default))
|
||||
reject('Couldn\'t send the acknowledgement packet : ' + err);
|
||||
|
||||
if (p7ReceivedPacketInfo.type !== p7PacketType.roleswap)
|
||||
reject('The calculator didn\'t respond with the expected packet : ' + p7ReceivedPacketInfo.type + ' (packet type) ' + p7ReceivedPacketInfo.subtype + ' (packet subtype).');
|
||||
|
||||
//Everything went right
|
||||
resolve(freeMemory);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
async function optimize(fileSystem) {
|
||||
let err = 0
|
||||
if (err = await p7SendExtendedCommandPacket(flashCommandSubtype.optimizeFilesystem, 0, 0, 0, ["", "", "", "", fileSystem, ""]))
|
||||
return "Couldn't optimize the fileSystem : " + err;
|
||||
return 0;
|
||||
'use strict'
|
||||
/*function test(){
|
||||
throw 'geswg';
|
||||
console.log('err');
|
||||
}
|
||||
|
||||
|
||||
/* Main function */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function talkToCalculator() {
|
||||
let err = await p7Initialization();
|
||||
if (err)
|
||||
return "Failed to initiate the connection : " + err;
|
||||
|
||||
console.log("%cExecute user request", "font-size: 14px; color: white");
|
||||
try {
|
||||
test();
|
||||
console.log('err');
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}*/
|
||||
|
||||
//if (err = fileTransfer(0, ))
|
||||
|
||||
let capacity = 0;
|
||||
console.log(getCapacity('fls0').then((success) => capacity = success, (failure) => failure));
|
||||
console.log(capacity);
|
||||
//var file = document.getElementById('input').files[0];
|
||||
//var file = await window.showOpenFilePicker();
|
||||
//await fileTransfer(file, "", 'fls0');
|
||||
//await list('fls0');
|
||||
//console.log(file);
|
||||
/* Terminate packet handling */
|
||||
|
||||
// //Check if the packet is a terminate packet
|
||||
// if (p7ReceivedPacketInfo.type === p7PacketType.terminate)
|
||||
// return 'The calculator closed the connection' + (err = await p7DecodeTerminatePacket()) ? ';but there was an error exiting the session : ' + err : '.';
|
||||
|
||||
|
||||
document.getElementById('demo').innerHTML =
|
||||
'Hardware identifier : ' + p7DeviceInformation['Hardware identifier'] +
|
||||
'<br>Processor identifier : ' + p7DeviceInformation['Processor identifier'] +
|
||||
'<br>Preprogrammed ROM capaciy : ' + p7DeviceInformation['Preprogrammed ROM capaciy']+
|
||||
'<br>Flash ROM capacity : ' + p7DeviceInformation['Flash ROM capacity'] +
|
||||
'<br>RAM capacity : ' + p7DeviceInformation['RAM capacity'] +
|
||||
'<br>Prepogrammed ROM version : ' + p7DeviceInformation['Prepogrammed ROM version'] +
|
||||
'<br>Boot code version : ' + p7DeviceInformation['Boot code version'] +
|
||||
'<br>Boot code offset : ' + p7DeviceInformation['Boot code offset'] +
|
||||
'<br>Boot code size : ' + p7DeviceInformation['Boot code size'] +
|
||||
'<br>Os code version : ' + p7DeviceInformation['Os code version'] +
|
||||
'<br>Os code offset : ' + p7DeviceInformation['Os code offset'] +
|
||||
'<br>Os code size : ' + p7DeviceInformation['Os code size'] +
|
||||
'<br>Protocol version : ' + p7DeviceInformation['Protocol version'] +
|
||||
'<br>Product ID : ' + p7DeviceInformation['Product ID'] +
|
||||
'<br>Name set by user in system : ' + p7DeviceInformation['Name set by user in system'];
|
||||
|
||||
await device.transferOut(1, p7SendBuffer.slice(0, p7MakeBasicPacket(p7PacketType['terminate'],
|
||||
terminateSubtype['default'])));
|
||||
}
|
||||
|
||||
|
||||
window.onload = (event) => {
|
||||
document.querySelector('#connect').onclick = async () => {
|
||||
let err = 0;
|
||||
|
||||
if (err = await talkToCalculator())
|
||||
console.log('%c%s', "color: red", err);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
699
internal.js
699
internal.js
|
@ -1,153 +1,189 @@
|
|||
"use strict";
|
||||
/* Compute the (p7-like) checksum of a buffer */
|
||||
function p7Checksum(buffer, length)
|
||||
{
|
||||
//Sum individual bytes in Subtype (ST) and following fields
|
||||
let checksum = 0;
|
||||
let i = 1;
|
||||
for(length -= 2 ; i < length ; i++ )
|
||||
checksum+=buffer[i];
|
||||
|
||||
/* NOT + 1, as defined in fxReverse documentation.
|
||||
var p7 = {
|
||||
device: {},
|
||||
make: {},
|
||||
decode: {},
|
||||
receive: {},
|
||||
send: {}
|
||||
};
|
||||
|
||||
|
||||
(function() {
|
||||
/* ---------------------Utilitaries--------------------- */
|
||||
|
||||
/* Sum individual bytes
|
||||
* NOT + 1, as defined in fxReverse documentation.
|
||||
* Be sure it's under 256! */
|
||||
return (((~checksum) + 1) & 0xFF);
|
||||
}
|
||||
Uint8Array.prototype.p7Checksum = function () {
|
||||
return (((~(this.reduce((accumulator, currentValue) => accumulator + currentValue))) + 1) & 0xFF)
|
||||
}
|
||||
|
||||
/* Return an array with the ascii values of each hex digit*/
|
||||
function p7HexToAscii(hexNumber, digits) {
|
||||
return p7StringToAscii(hexNumber.toString(16).toUpperCase().padStart(digits, 0));
|
||||
}
|
||||
/* Convert a string into an array of ascii numbers */
|
||||
String.prototype.toAscii = function () {
|
||||
return this.split('').map((char) => char.charCodeAt(0))
|
||||
}
|
||||
|
||||
/* Return an array with the ascii value of each character */
|
||||
function p7StringToAscii(string) {
|
||||
return string.split('').map(letter => letter.charCodeAt(0));
|
||||
}
|
||||
/* Convert an hex number into an array of ascii values
|
||||
* Use the uppercase representation of the number */
|
||||
Number.prototype.hexToAscii = function (padding) {
|
||||
return this.toString(16).toUpperCase().padStart(padding, 0).toAscii();
|
||||
}
|
||||
|
||||
/* Create a basic (Non-Extended) packet and push it to p7SendBuffer */
|
||||
/* return it's length (6) */
|
||||
function p7MakeBasicPacket(type, subtype) {
|
||||
//Set Type (T) field
|
||||
p7SendBuffer.set([type], 0);
|
||||
/* Convert an ascii array into a string */
|
||||
p7.asciiToString = (array) => String.fromCharCode.apply(null, array);
|
||||
|
||||
//Set Subtype (ST) field
|
||||
p7SendBuffer.set(p7HexToAscii(subtype, 2), 1);
|
||||
/* Convert an ascii array representing an hex number into a number */
|
||||
//Uint8Array.prototype.fromAsc
|
||||
p7.asciiToHex = (array) => Number('0x' + p7.asciiToString(array));
|
||||
|
||||
|
||||
p7.sendBuffer = new Uint8Array(1032);
|
||||
p7.receiveBuffer = undefined;//new Uint8Array(1032 + 1);
|
||||
|
||||
/* ---------------------Packet making--------------------- */
|
||||
|
||||
/* Create a basic (Non-Extended) packet and push it to p7.sendBuffer */
|
||||
/* return it's length (6) */
|
||||
p7.make.basicPacket = (type, subtype) => {
|
||||
//Set the Type (T), Subtype (ST) and Extended (EX) fields
|
||||
p7.sendBuffer.set([type]
|
||||
.concat(subtype.hexToAscii(2))
|
||||
.concat([0x30])
|
||||
, 0);
|
||||
|
||||
//Set the Checksum (CS) field
|
||||
p7.sendBuffer.set(p7.sendBuffer.slice(1, 4).p7Checksum().hexToAscii(2), 4);
|
||||
|
||||
//Set Extended (EX) field
|
||||
p7SendBuffer.set([0x30], 3);
|
||||
//Return the packet length
|
||||
return 6;
|
||||
}
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7SendBuffer.set(p7HexToAscii(p7Checksum(p7SendBuffer, 6), 2), 4);
|
||||
|
||||
//Return basic packet length
|
||||
return 6;
|
||||
}
|
||||
/* Fill the Data (D) field of a command packet in p7.sendBuffer */
|
||||
/* return the Data (D) field length */
|
||||
p7.make.commandPacketDataField = function (dataType, fileSize, commandArguments) {
|
||||
//Set Overwrite (OW), Data type (DT) and File size (FS) fields
|
||||
p7.sendBuffer.set([0x30, 0x30, /* Overwrite */
|
||||
0x30, 0x30] /* Data type field ?? */
|
||||
.concat(fileSize.hexToAscii(8)) /* File size field */
|
||||
, 8);
|
||||
|
||||
/* Fill Data (D) field of a command packet in p7SendBuffer */
|
||||
/* return Data (D) field length */
|
||||
function p7MakeCommandPacketDataField(forceOverwrite, dataType, fileSize, commandArguments) {
|
||||
//Set Overwrite (OW) field
|
||||
p7SendBuffer.set([0x30, (forceOverwrite) ? ((forceOverwrite == 1) ? 0x31 : 0x32) : 0x30], 8);
|
||||
|
||||
let index = 18;
|
||||
//Set Size of Data {1-6} (SD{1-6}) fields
|
||||
commandArguments.forEach(element => p7.sendBuffer.set(element.length.hexToAscii(2), (index += 2)));
|
||||
|
||||
//Set Data {1-6} (D{1-6}) fields
|
||||
let data = commandArguments.join('');
|
||||
p7.sendBuffer.set(data.toAscii(), 32);
|
||||
|
||||
return data.length + 24; /* Overwrite (OW), Data type (DT), File size (FS) and Data size (DS) subfields of the Data (D) field of the packet */;
|
||||
}
|
||||
|
||||
//Set Data type (DT) field ????
|
||||
p7SendBuffer.set([0x30, 0x30], 10);
|
||||
/* Create an extended command packet and push it to p7.sendBuffer */
|
||||
/* return it's length */
|
||||
p7.make.extendedCommandPacket = function (subtype, dataType, fileSize, commandArguments) {
|
||||
let dataSize = p7.make.commandPacketDataField(dataType, fileSize, commandArguments); /* Data field */
|
||||
|
||||
//Set Type (T), Subtype (ST), Extended (EX) and Data size (DT) fields
|
||||
p7.sendBuffer.set([0x01] /* Type field */
|
||||
.concat(subtype.hexToAscii(2)) /* Subtype field */
|
||||
.concat([0x31]) /* Extended field */
|
||||
.concat(dataSize.hexToAscii(4)) /* Data size field */
|
||||
, 0);
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7.sendBuffer.set(p7.sendBuffer.slice(1, dataSize + 8).p7Checksum().hexToAscii(2), dataSize + 8);
|
||||
|
||||
//Set Filesize (FS) field
|
||||
p7SendBuffer.set(p7HexToAscii(fileSize, 8), 12);
|
||||
//Return it's length
|
||||
return dataSize + 10 /* Type (T), Subtype (ST), Extended (EX), Data size (DT) and Checksum (CS) fields */;
|
||||
}
|
||||
|
||||
let packetSize = 20;
|
||||
/* Create a data packet and push it to p7.sendBuffer */
|
||||
/* return it's length */
|
||||
p7.make.dataPacket = function (subType, totalNumber, currentNumber, data) {
|
||||
/* Set Type (T), Subtype (ST), Extended (EX), Data size (DS),
|
||||
* Data (D) fields and Data (D) subfields :
|
||||
* Total Number (TN), Current Number (CN), and Data (DD) */
|
||||
p7.sendBuffer.set([0x02] /* Type field */
|
||||
.concat(subType.hexToAscii(2)) /* Subtype (ST) field */
|
||||
.concat([0x31]) /* Extended (EX) field */
|
||||
.concat( /* Data size (DS) field */
|
||||
(data.length + 8 /* Total number (TN) and Current number (CN) subfields */ ).hexToAscii(4))
|
||||
.concat(totalNumber.hexToAscii(4)) /* Total number (TN) subfield */
|
||||
.concat(currentNumber.hexToAscii(4)) /* Current number (CN) subfield */
|
||||
.concat(data) /* Data (DD) subfield */
|
||||
, 0);
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7.sendBuffer.set(p7.sendBuffer.slice(1, data.length + 16).p7Checksum().hexToAscii(2), data.length + 16);
|
||||
|
||||
//Set Size of Data {1-6} (SD{1-6}) field
|
||||
for (let i = 0 ; i < 6 ; packetSize += 2 , i++)
|
||||
p7SendBuffer.set((commandArguments[i]) ? p7HexToAscii(commandArguments[i].length, 2) : [0x30, 0x30], packetSize);
|
||||
|
||||
|
||||
//Set Data {1-6} (D{1-6}) field
|
||||
for (let i = 0 ; i < 6 ; i++)
|
||||
if (commandArguments[i]) {
|
||||
p7SendBuffer.set(p7StringToAscii(commandArguments[i]), packetSize);
|
||||
packetSize += commandArguments[i].length;
|
||||
//Return it's length
|
||||
return data.length + 18 /* All other fields and subfields */;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------Packet decoding--------------------- */
|
||||
|
||||
/* Return all the informations of the device, and trim string's overage (255) */
|
||||
p7.decode.extendedAckPacket = () => {
|
||||
return {
|
||||
hardwareIdentifier : p7.asciiToString(p7ReceiveBuffer.slice(8, 16)),
|
||||
processorIdentifier : p7.asciiToString(p7ReceiveBuffer.slice(16, 32)),
|
||||
preprogrammedROMCapacity : p7.asciiToString(p7ReceiveBuffer.slice(32, 40)),
|
||||
flashROMCapacity : p7.asciiToString(p7ReceiveBuffer.slice(40, 48)),
|
||||
ramCapacity : p7.asciiToString(p7ReceiveBuffer.slice(48, 56)),
|
||||
prepogrammedROMVersion : p7.asciiToString(p7ReceiveBuffer.slice(56, 72).filter(number => number !== 255)),
|
||||
bootCodeVersion : p7.asciiToString(p7ReceiveBuffer.slice(72, 88).filter(number => number !== 255)),
|
||||
bootCodeOffset : p7.asciiToString(p7ReceiveBuffer.slice(88, 96).filter(number => number !== 255)),
|
||||
bootCodeSize : p7.asciiToString(p7ReceiveBuffer.slice(96, 104).filter(number => number !== 255)),
|
||||
osCodeVersion : p7.asciiToString(p7ReceiveBuffer.slice(104, 120).filter(number => number !== 255)),
|
||||
osCodeOffset : p7.asciiToString(p7ReceiveBuffer.slice(120, 128)),
|
||||
osCodeSize : p7.asciiToString(p7ReceiveBuffer.slice(128, 136)),
|
||||
protocolVersion : p7.asciiToString(p7ReceiveBuffer.slice(136, 140)),
|
||||
productID : p7.asciiToString(p7ReceiveBuffer.slice(140, 156).filter(number => number !== 255)),
|
||||
username : p7.asciiToString(p7ReceiveBuffer.slice(156, 172).filter(number => number !== 255))
|
||||
}
|
||||
};
|
||||
|
||||
/* Return the value (as an number) of the Filesize (FS) subfield of the Data (D) field of an extended command packet */
|
||||
p7.decode.commandPacketFilesize = () => p7.asciiToHex(p7.receiveBuffer.slice(12, 20));
|
||||
|
||||
/* ---------------------Packet receiving--------------------- */
|
||||
|
||||
/* Doesn't work for now on */
|
||||
p7.receive.packet = async function () {
|
||||
/*try {
|
||||
let array = undefined;
|
||||
do {
|
||||
array = await p7.device.transferIn(2, 64);
|
||||
console.log(array);
|
||||
} while (array.data.byteLength == 0)
|
||||
|
||||
p7.receiveBuffer = Uint8Array(await p7.device.transferIn(2, 64).data.buffer);
|
||||
} catch (err) {
|
||||
throw new Error("Couldn't receive the first 64 bytes of the packet : " + err.message);
|
||||
}
|
||||
|
||||
return packetSize - 8; /* Type, Subtype, Extended, Data size fields of the packet */;
|
||||
}
|
||||
let packetInfo = {};
|
||||
|
||||
//Set Type (T) field
|
||||
packetInfo.type = p7.receiveBuffer[0];
|
||||
|
||||
/* Create an extended command packet and push it to p7SendBuffer */
|
||||
/* return it's length */
|
||||
function p7MakeExtendedCommandPacket(subtype, forceOverwrite, dataType, fileSize, commandArguments) {
|
||||
//Set Type (T) field
|
||||
p7SendBuffer.set([0x01], 0);
|
||||
//Set Subtype (ST) field
|
||||
packetInfo.subtype = p7.asciiToHex(p7.receiveBuffer.slice(1, 2));
|
||||
|
||||
//Set Subtype (ST) field
|
||||
p7SendBuffer.set(p7HexToAscii(subtype, 2), 1);
|
||||
//Set Extended (EX) field
|
||||
packetInfo.extended = (p7.receiveBuffer[3] === 0x31);
|
||||
|
||||
//Set Extended (EX) field
|
||||
p7SendBuffer.set([0x31], 3);
|
||||
|
||||
//Set Data (D) field
|
||||
let dataSize = p7MakeCommandPacketDataField(forceOverwrite, dataType, fileSize, commandArguments);
|
||||
|
||||
//Set Data size (DS) field
|
||||
p7SendBuffer.set(p7HexToAscii(dataSize, 4), 4);
|
||||
|
||||
let packetSize = dataSize + 10 /* Type, Subtype, Extended, Data size and Checksum fields */;
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7SendBuffer.set(p7HexToAscii(p7Checksum(p7SendBuffer, packetSize), 2), packetSize - 2);
|
||||
|
||||
//Return it's length
|
||||
return packetSize;
|
||||
}
|
||||
|
||||
/* Create a data packet and push it to p7SendBuffer */
|
||||
/* return it's length */
|
||||
function p7MakeDataPacket(subType, totalNumber, currentNumber, data) {
|
||||
packetSize = data.length + 18 /* Type, Subtype, Extended, Data size, Data['Total Number'], Data['Current number'] and checksum fields */;
|
||||
|
||||
//Set Type (T) field
|
||||
p7SendBuffer.set([0x02], 0);
|
||||
|
||||
//Set Subtype (ST) field
|
||||
p7SendBuffer.set(p7HexToAscii(subType, 2), 1);
|
||||
|
||||
//Set Extended (EX) field
|
||||
p7SendBuffer.set([0x31], 3);
|
||||
|
||||
//Set Data size (DS) field
|
||||
p7SendBuffer.set(p7HexToAscii(data.length + 8 /* Total number (TN) and Current number (CN) fields */, 4), 4);
|
||||
|
||||
//Set Total number (TN) field
|
||||
p7SendBuffer.set(p7HexToAscii(totalNumber, 4), 8);
|
||||
|
||||
//Set Current number (CN) field
|
||||
p7SendBuffer.set(p7HexToAscii(currentNumber, 4), 12);
|
||||
|
||||
//Set Data (DD) field
|
||||
p7SendBuffer.set(data, 16);
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7SendBuffer.set(p7HexToAscii(p7Checksum(p7SendBuffer, packetSize), 2), packetSize - 2);
|
||||
|
||||
//Return it's length
|
||||
return packetSize;
|
||||
}
|
||||
|
||||
/* Receive a packet and parse it's properties to p7ReceivedPacketInfo */
|
||||
/* Make sure their aren't checksums error (ask for a resend if necessary) */
|
||||
async function p7ReceivePacket() {
|
||||
console.log("%cReceiving...", "color: orange");
|
||||
let checksumError = 0;
|
||||
let err = 0;
|
||||
do {
|
||||
//Send an error packet with subtype resend request if there was a checksum error
|
||||
if (checksumError)
|
||||
if (err = await p7SendBasicPacket(p7PacketType.error, errorSubtype.resendRequest))
|
||||
return "Couldn't send an error packet with resend request subtype (there was a checksum error) : " + err;
|
||||
console.log(packetInfo);
|
||||
*/
|
||||
|
||||
let transferInResult = 0;
|
||||
|
||||
let err = 0;
|
||||
//Recieve and parse the packet
|
||||
do {
|
||||
transferInResult = await device.transferIn(2, 64).then(
|
||||
transferInResult = await p7.device.transferIn(2, 64).then(
|
||||
(result) => {
|
||||
return result;
|
||||
}, (error) => {
|
||||
|
@ -155,274 +191,195 @@ async function p7ReceivePacket() {
|
|||
});
|
||||
if (err)
|
||||
return "Couldn't receive the first 64 bytes of the packet : " + err;
|
||||
console.log('retrying');
|
||||
} while(!transferInResult.data.byteLength);
|
||||
|
||||
|
||||
p7ReceivedPacketInfo.packetSize = 4; /*Type, Subtype and Extended field*/
|
||||
|
||||
//p7ReceivedPacketInfo.packetSize = 4; /*Type, Subtype and Extended field*/
|
||||
|
||||
//Copy the received buffer to p7ReceiveBuffer
|
||||
p7ReceiveBuffer.set(new Uint8Array(transferInResult.data.buffer), 0);
|
||||
p7.receiveBuffer.set(new Uint8Array(transferInResult.data.buffer), 0);
|
||||
console.log(p7.receiveBuffer.slice(0, 25));
|
||||
}
|
||||
|
||||
//Set Type (T) field
|
||||
p7ReceivedPacketInfo.type = p7ReceiveBuffer[0];
|
||||
/* ---------------------Packet sending--------------------- */
|
||||
|
||||
//Set Subtype (ST) field
|
||||
p7ReceivedPacketInfo.subtype = Number('0x' + String.fromCharCode(p7ReceiveBuffer[1], p7ReceiveBuffer[2]), 16);
|
||||
|
||||
//Set Extended (EX) field
|
||||
p7ReceivedPacketInfo.extended = (p7ReceiveBuffer[3] === 0x31);
|
||||
|
||||
if (!p7ReceivedPacketInfo.extended) {
|
||||
p7ReceivedPacketInfo.packetSize += 2; /*Checksum field*/
|
||||
/* Doesn't work for now on */
|
||||
p7.send.packet = async function (length) {
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7ReceivedPacketInfo.checksum = Number('0x' + String.fromCharCode(p7ReceiveBuffer[4], p7ReceiveBuffer[5]), 16);
|
||||
|
||||
//Compute the checksum
|
||||
checksumError = (p7ReceivedPacketInfo.checksum !== p7Checksum(p7ReceiveBuffer, p7ReceivedPacketInfo.packetSize));
|
||||
/*try {
|
||||
await p7.device.transferOut(1, p7.sendBuffer.slice(0, length));
|
||||
} catch (err) {
|
||||
throw new Error("Couldn't send the packet : " + err.message);
|
||||
}*/
|
||||
|
||||
let err = 0;
|
||||
|
||||
//Send the packet and return the error on failure
|
||||
if (err = await p7.device.transferOut(1, p7.sendBuffer.slice(0, length)).then((success) => 0, (failure) => failure))
|
||||
return "Couldn't send the packet : " + err;
|
||||
};
|
||||
|
||||
/* ---------------------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 : " + err.message);
|
||||
}
|
||||
else {
|
||||
|
||||
p7ReceivedPacketInfo.packetSize += 4; /*Data size field*/
|
||||
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 */
|
||||
|
||||
//Set Data size (DS) field
|
||||
p7ReceivedPacketInfo.dataSize = Number('0x' + String.fromCharCode.apply(null, p7ReceiveBuffer.slice(4, 8)), 10);
|
||||
console.log(p7.device);
|
||||
|
||||
//Add the checksum bytes
|
||||
p7ReceivedPacketInfo.dataSize+=2;
|
||||
/* Everything went right */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End the connexion with the calculator */
|
||||
p7.exit = async function () {
|
||||
|
||||
}
|
||||
|
||||
|
||||
p7ReceivedPacketInfo.packetSize += (p7ReceivedPacketInfo.dataSize > 56) ? 56 : p7ReceivedPacketInfo.dataSize;
|
||||
p7ReceivedPacketInfo.dataSize -= 56;
|
||||
|
||||
document.getElementById('connect').addEventListener('click', async function () {
|
||||
try {
|
||||
await p7.init();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
//Receive the rest of the data
|
||||
while(p7ReceivedPacketInfo.dataSize > 0)
|
||||
{
|
||||
transferInResult = await device.transferIn(2, 64).then(
|
||||
(result) => {
|
||||
return result;
|
||||
}, (error) => {
|
||||
err = error;
|
||||
});
|
||||
/* 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;
|
||||
* }
|
||||
|
||||
if (err)
|
||||
return "Couldn't receive the " + packetSize + "th and following 64 bytes of the packet : " + err;
|
||||
|
||||
p7ReceiveBuffer.set(new Uint8Array(transferInResult.data.buffer), p7ReceivedPacketInfo.packetSize);
|
||||
p7ReceivedPacketInfo.packetSize += (p7ReceivedPacketInfo.dataSize > 64) ? 64 : p7ReceivedPacketInfo.dataSize;
|
||||
p7ReceivedPacketInfo.dataSize-=64;
|
||||
****************************************************************
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//Set Checksum (CS) field
|
||||
p7ReceivedPacketInfo.checksum = Number('0x' + String.fromCharCode(p7ReceiveBuffer[p7ReceivedPacketInfo.packetSize - 2], p7ReceiveBuffer[p7ReceivedPacketInfo.packetSize - 1]), 16);
|
||||
|
||||
//Compute the checksum
|
||||
checksumError = (p7ReceivedPacketInfo.checksum !== p7Checksum(p7ReceiveBuffer, p7ReceivedPacketInfo.packetSize));
|
||||
}
|
||||
} while (checksumError)
|
||||
console.log(p7ReceivedPacketInfo);
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* Send a packet */
|
||||
/* Receive the response and resend the packet if the response was an error with subtype resend request */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7SendPacket(packetLength) {
|
||||
console.log(p7SendBuffer.slice(0, packetLength));
|
||||
controlData = new Uint8Array(transferInResult.data.buffer);
|
||||
|
||||
let err = 0;
|
||||
console.log(controlData);
|
||||
|
||||
//Send the packet and return the error on failure
|
||||
if (err = await device.transferOut(1, p7SendBuffer.slice(0, packetLength)).then((success) => 0, (failure) => failure))
|
||||
return "Couldn't send the packet : " + err;
|
||||
try {
|
||||
await p7.device.controlTransferOut({
|
||||
requestType: 'vendor',
|
||||
recipient: 'interface',
|
||||
request: 0x01,
|
||||
value: 0x0000,
|
||||
index: 0x0000
|
||||
}, controlData);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} */
|
||||
|
||||
//Receive the packet and return the error on failure
|
||||
if (err = await p7ReceivePacket())
|
||||
return "Couldn't receive the response packet : " + err;
|
||||
p7.make.basicPacket(0x06, 0x00);
|
||||
console.log(p7.sendBuffer.slice(0, 8));
|
||||
/*
|
||||
try {
|
||||
await p7.send.packet(6);
|
||||
} catch (err) {
|
||||
console.log('err');
|
||||
}*/
|
||||
|
||||
//Resend the packet if the response was an error packet with subtype resend request and return the error on failure
|
||||
for (let i = 0 ; (p7ReceivedPacketInfo.type === p7PacketType.error && p7ReceivedPacketInfo.subtype === errorSubtype.resendRequest) ; i++) {
|
||||
let err = 0;
|
||||
if (err = await p7.send.packet(6))
|
||||
console.log('err' + err);
|
||||
|
||||
if (err = await device.transferOut(1, p7SendBuffer.slice(0, packetLength)).then((success) => {console.log(success) ; return 0}, (failure) => {return failure}))
|
||||
return "Couldn't send the packet : " + err;
|
||||
if (err = await p7ReceivePacket())
|
||||
return "Couldn't receive the response packet : " + err;
|
||||
if (i > 2)
|
||||
return "Too much resend request, the calculator might be broken.";
|
||||
}
|
||||
/* Error: Stay in an endless loop */
|
||||
await p7.receive.packet();
|
||||
});
|
||||
|
||||
//Everything went right
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Send a basic (non-Extended) packet */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7SendBasicPacket(type, subtype) {
|
||||
console.log("%cSending basic packet...", "color: green");
|
||||
return await p7SendPacket(p7MakeBasicPacket(type, subtype));
|
||||
}
|
||||
|
||||
/* Send an extended command packet */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7SendExtendedCommandPacket(subtype, forceOverwrite, dataType, fileSize, commandArguments) {
|
||||
console.log("%cSending extended command packet...", "color: green");
|
||||
return await p7SendPacket(p7MakeExtendedCommandPacket(subtype, forceOverwrite, dataType, fileSize, commandArguments));
|
||||
}
|
||||
|
||||
/* Send an extended data packet */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7SendDataPacket(subtype, totalNumber, currentNumber, data) {
|
||||
console.log("%cSending data packet...", "color: green");
|
||||
return p7SendPacket(p7MakeDataPacket(subtype, totalNumber, currentNumber, data));
|
||||
}
|
||||
|
||||
/* Split the data into 256 bytes-long buffer and send all of them */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7SendData(subtype, data) {
|
||||
let err = 0;
|
||||
let lastPacketSize = (data.byteLength & 255); //Equivalent to data.byteLength % 256, but way faster !
|
||||
let totalPacketNumber = (data.byteLength >> 8); //Equivalent to data.byteLength / 256, but way way waaaaaay faster, and return an integer quotient, not a decimal one !!
|
||||
console.log(lastPacketSize + ' ' + totalPacketNumber);
|
||||
totalPacketNumber += (lastPacketSize) ? 1 : 0;
|
||||
let currentPacketNumber = 1;
|
||||
let currentPacketFirstByteIndex = 0;
|
||||
|
||||
//Send all the 256 bytes-long data packets
|
||||
for (; currentPacketNumber < totalPacketNumber ; currentPacketNumber++)
|
||||
if (err = await p7SendDataPacket(subtype, totalPacketNumber, currentPacketNumber, data.slice(currentPacketFirstByteIndex, (currentPacketFirstByteIndex += 256))))
|
||||
return 'Couldn\'t send the ' + currentPacketNumber + ' data packet : ' + err;
|
||||
|
||||
//Send the last data packet (if it exists)
|
||||
if (lastPacketSize)
|
||||
if (err = await p7SendDataPacket(subtype, totalPacketNumber, currentPacketNumber, data.slice(currentPacketFirstByteIndex, currentPacketFirstByteIndex + lastPacketSize)))
|
||||
return 'Couldn\'t send the last data packet (' + lastPacketSize + ' bytes) : ' + err;
|
||||
|
||||
|
||||
console.log(p7SendBuffer.slice(0, 64));
|
||||
console.log(p7ReceivedPacketInfo);
|
||||
|
||||
//Everything went allright
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set all device information feilds, and trim string's overage ('ÿ') */
|
||||
function p7DecodeExtendedAckPacket() {
|
||||
p7DeviceInformation['Hardware identifier'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(8, 16));
|
||||
p7DeviceInformation['Processor identifier'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(16, 32));
|
||||
p7DeviceInformation['Preprogrammed ROM capacity'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(32, 40));
|
||||
p7DeviceInformation['Flash ROM capacity'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(40, 48));
|
||||
p7DeviceInformation['RAM capacity'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(48, 56));
|
||||
p7DeviceInformation['Prepogrammed ROM version'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(56, 72)).replaceAll('ÿ', '');;
|
||||
p7DeviceInformation['Boot code version'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(72, 88)).replaceAll('ÿ', '');
|
||||
p7DeviceInformation['Boot code offset'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(88, 96)).replaceAll('ÿ', '');
|
||||
p7DeviceInformation['Boot code size'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(96, 104)).replaceAll('ÿ', '');
|
||||
p7DeviceInformation['Os code version'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(104, 120)).replaceAll('ÿ', '');
|
||||
p7DeviceInformation['Os code offset'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(120, 128));
|
||||
p7DeviceInformation['Os code size'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(128, 136));
|
||||
p7DeviceInformation['Protocol version'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(136, 140));
|
||||
p7DeviceInformation['Product ID'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(140, 156)).replaceAll('ÿ', '');;
|
||||
p7DeviceInformation['Name set by user in system'] = String.fromCharCode.apply(null, p7ReceiveBuffer.slice(156, 172)).replaceAll('ÿ', '');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode a terminate packet and close the connection */
|
||||
async function p7DecodeTerminatePacket() {
|
||||
let err = 0;
|
||||
switch (p7ReceivedPacketInfo.subtype) {
|
||||
case terminateSubtype.default:
|
||||
alert('The calculator asked to close the connection.');
|
||||
case terminateSubtype.userRequest:
|
||||
alert('The calculator said you closed the connection!');
|
||||
case terminateSubtype.timeouts:
|
||||
alert('The calculator closed the connection because it was inactive for more than 6 minutes.');
|
||||
case terminateSubtype.overwriteRequest:
|
||||
alert('The calculator didn\'t accept the overwrite request and closed the connection.');
|
||||
default:
|
||||
alert('The calculator asked to terminate communication for an unknown reason : 0x' + p7ReceivedPacketInfo.subtype.toString(16) + ' (the hex code of the reason).');
|
||||
}
|
||||
if (err = await p7SendBasicPacket(p7PacketType.ack, ackSubtype.default))
|
||||
return 'Couldn\'t send acknowledgement packet : ' + err;
|
||||
return (err = await p7Exit()) ? 'Couldn\'t exit properly : ' + err : 0;
|
||||
}
|
||||
|
||||
/* Return the value (as an number) of Filesize (FS) subfield of Data (D) field of an extended command packet */
|
||||
function p7CommandPacketGetFilesize() {
|
||||
return Number('0x' + String.fromCharCode.apply(null, p7ReceiveBuffer.slice(12, 20)), 16);
|
||||
}
|
||||
|
||||
/* Return the trimed receive buffer only containing Data (DD) subfield of Data (D) field of an extended command packet */
|
||||
function p7CommandPacketGetField(field) {
|
||||
let fieldStart = 32; /* D1 field first byte's position */
|
||||
for (let i = 0 ; i < 2 * field ; i += 2)
|
||||
fieldStart += Number('0x' + String.fromCharCode(p7ReceiveBuffer[20 + i], p7ReceiveBuffer[21 + i]), 16);
|
||||
|
||||
let fieldEnd = fieldStart + Number('0x' + String.fromCharCode(p7ReceiveBuffer[20 + 2 * field], p7ReceiveBuffer[21 + 2 * field]), 16);
|
||||
return p7ReceiveBuffer.slice(fieldStart, fieldEnd);
|
||||
}
|
||||
|
||||
/* Connect to the calculator */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7Initialization() {
|
||||
let err = 0;
|
||||
err = await navigator.usb.requestDevice({filters:[{'vendorId': 0x07cf , 'productId': 0x6101}, {'vendorId': 0x07cf , 'productId': 0x6102}]}).then(
|
||||
(selectedDevice) => {
|
||||
device = selectedDevice;
|
||||
return 0;
|
||||
}, (error) => error
|
||||
);
|
||||
|
||||
if (err)
|
||||
return "Couldn't get the selected device (maybe the user didn't select one) : " + err;
|
||||
|
||||
if (err = await device.open().then(() => 0, (error) => error))
|
||||
return "Couldn't connect to the calculator : " + err;
|
||||
|
||||
//It's the only existing configuration (should be selected by default), just checkin'
|
||||
if (err = await device.selectConfiguration(1).then(() => 0, (error) => error))
|
||||
return "Couldn't select the configuration (configurationValue : 1) : " + err;
|
||||
|
||||
if (err = await device.claimInterface(0 /* It's the only existing one */).then(() => 0, (error) => error))
|
||||
return "Couldn't claim the interface (interfaceNumber : 0) : " + err;
|
||||
|
||||
console.log(device);
|
||||
|
||||
console.log('%cInitialisation packet', "font-size: 14px; color: white");
|
||||
|
||||
if (err = await p7SendBasicPacket(p7PacketType['check'], checkSubtype['initialization']))
|
||||
return "Failed to send init packet : " + err;
|
||||
|
||||
|
||||
if (!(p7ReceivedPacketInfo.type === p7PacketType.ack && p7ReceivedPacketInfo.subtype === ackSubtype.default))
|
||||
return "Not the expected response packet."; /* TODO: handle this error */
|
||||
|
||||
|
||||
console.log('%cRequesting device\'s informations', "font-size: 14px; color: white");
|
||||
|
||||
|
||||
if (err = await p7SendBasicPacket(p7PacketType['command'], sysCommandSubtype['getDeviceInfo']))
|
||||
return "Failed to request device info : " + err;
|
||||
|
||||
if (!(p7ReceivedPacketInfo.type === p7PacketType.ack && p7ReceivedPacketInfo.subtype === ackSubtype.extendedAck))
|
||||
return "Not the expected response packet."; /* TODO: add a handle to this error */
|
||||
|
||||
p7DecodeExtendedAckPacket();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Disconnect from the calculator */
|
||||
/* Return 0 on success and the error on failure */
|
||||
async function p7Exit() {
|
||||
let err = 0;
|
||||
return (err = await device.close().then((success) => {return 0}, (failure) => {return failure})) ? "There was an error disconnecting from the calculator : " + err : 0;
|
||||
}
|
||||
|
||||
/* Return an object describing a file (or a directory) */
|
||||
function createFileObject(device, path, name, size) {
|
||||
//Directories never have size, only their own path
|
||||
return (size) ? {type: 'file', path: path, name: name, size: size} : {type: 'directory', path: path};
|
||||
}
|
||||
})();
|
Loading…
Reference in New Issue