2021-07-14 18:31:10 +02:00
"use strict" ;
2021-08-06 13:06:21 +02:00
var p7 = { } ;
2021-07-14 18:31:10 +02:00
2021-07-21 17:13:22 +02:00
2021-07-20 15:12:43 +02:00
( function ( ) {
/* ---------------------Utilitaries--------------------- */
2021-07-14 18:31:10 +02:00
2021-07-20 15:12:43 +02:00
/* Convert a string into an array of ascii numbers */
String . prototype . toAscii = function ( ) {
return this . split ( '' ) . map ( ( char ) => char . charCodeAt ( 0 ) )
}
2021-07-14 18:31:10 +02:00
2021-07-20 15:12:43 +02:00
/ * C o n v e r t a n h e x n u m b e r i n t o a n a r r a y o f a s c i i v a l u e s
* Use the uppercase representation of the number * /
Number . prototype . hexToAscii = function ( padding ) {
return this . toString ( 16 ) . toUpperCase ( ) . padStart ( padding , 0 ) . toAscii ( ) ;
}
2021-08-06 13:06:21 +02:00
/ * S u m i n d i v i d u a l b y t e s
* NOT + 1 , as defined in fxReverse documentation .
* Be sure it ' s under 256 ! * /
Array . prototype . p7Checksum = function ( ) {
return ( ( ( ~ ( this . reduce ( ( accumulator , currentValue ) => accumulator + currentValue ) ) ) + 1 ) & 0xFF )
}
/* Add the Checksum (CS) field to a packet */
Array . prototype . addP7Checksum = function ( ) {
return this . concat ( this . slice ( 1 , this . length ) . p7Checksum ( ) . hexToAscii ( 2 ) ) ;
}
2021-07-14 18:31:10 +02:00
2021-07-20 15:12:43 +02:00
/* Convert an ascii array into a string */
2021-08-06 13:06:21 +02:00
Array . prototype . asciiToString = function ( ) {
2021-07-20 22:44:53 +02:00
let string = [ ] ;
this . forEach ( ( element ) => string . push ( String . fromCharCode ( element ) ) ) ;
return string . join ( '' ) ;
}
2021-07-14 18:31:10 +02:00
2021-07-20 15:12:43 +02:00
/* Convert an ascii array representing an hex number into a number */
2021-08-06 13:06:21 +02:00
Array . prototype . asciiToHex = function ( ) {
2021-07-20 22:44:53 +02:00
return Number ( '0x' + this . asciiToString ( ) ) ;
}
2021-07-14 18:31:10 +02:00
2021-08-06 13:06:21 +02:00
/* Return the decoded Data (D) field */
Array . prototype . decodeDataField = function ( ) {
let buffer = [ ... this ]
buffer . forEach ( ( element , index ) => {
if ( element === 0x5C )
buffer . splice ( index , 2 , buffer [ index + 1 ] - ( buffer [ index + 1 ] !== 0x5C ) * 0x20 ) ;
} ) ;
return buffer ;
2021-07-20 15:12:43 +02:00
}
2021-07-14 18:31:10 +02:00
2021-08-06 13:06:21 +02:00
/* Return the encoded Data (D) field */
Array . prototype . encodeDataField = function ( ) {
return this . flatMap ( ( element ) => ( element < 0x20 ) ? [ 0x5C , ( element + 0x20 ) ] : ( element === 0x5C ) ? [ 0x5C , 0x5C ] : element ) ;
}
2021-07-20 15:12:43 +02:00
/* Return all the informations of the device, and trim string's overage (255) */
2021-08-06 13:06:21 +02:00
Array . prototype . extendedAckPacket = function ( ) {
2021-07-20 15:12:43 +02:00
return {
2021-08-06 13:06:21 +02:00
hardwareIdentifier : this . slice ( 8 , 16 ) . asciiToString ( ) ,
processorIdentifier : this . slice ( 16 , 32 ) . asciiToString ( ) ,
preprogrammedROMCapacity : this . slice ( 32 , 40 ) . asciiToString ( ) ,
flashROMCapacity : this . slice ( 40 , 48 ) . asciiToString ( ) ,
ramCapacity : this . slice ( 48 , 56 ) . asciiToString ( ) ,
prepogrammedROMVersion : this . slice ( 56 , 72 ) . asciiToString ( ) ,
bootCodeVersion : this . slice ( 72 , 88 ) . asciiToString ( ) ,
bootCodeOffset : this . slice ( 88 , 96 ) . asciiToString ( ) ,
bootCodeSize : this . slice ( 96 , 104 ) . asciiToString ( ) ,
osCodeVersion : this . slice ( 104 , 120 ) . filter ( number => number !== 0xFF ) . asciiToString ( ) ,
osCodeOffset : this . slice ( 120 , 128 ) . asciiToString ( ) ,
osCodeSize : this . slice ( 128 , 136 ) . asciiToString ( ) ,
protocolVersion : this . slice ( 136 , 140 ) . asciiToString ( ) ,
productID : this . slice ( 140 , 156 ) . filter ( number => number !== 0xFF ) . asciiToString ( ) ,
username : this . slice ( 156 , 172 ) . filter ( number => number !== 0xFF ) . asciiToString ( )
2021-07-20 15:12:43 +02:00
}
} ;
2021-07-22 18:25:57 +02:00
2021-08-06 13:06:21 +02:00
/* Return the value (as an number) of the Overwrite (OW) subfield of the Data (D) field of an extended command packet */
Array . prototype . commandPacketOverWrite = function ( ) {
return this . slice ( 8 , 10 ) . asciiToHex ( ) ;
}
2021-07-22 18:25:57 +02:00
2021-08-06 13:06:21 +02:00
/* Return the value (as an number) of the Data type (DT) subfield of the Data (D) field of an extended command packet */
Array . prototype . commandPacketDataType = function ( ) {
return this . slice ( 10 , 12 ) . asciiToHex ( ) ;
}
2021-07-22 18:25:57 +02:00
2021-08-06 13:06:21 +02:00
/* Return the value (as an number) of the FileSize (FS) subfield of the Data (D) field of an extended command packet */
Array . prototype . commandPacketFileSize = function ( ) {
return this . slice ( 12 , 20 ) . asciiToHex ( ) ;
}
2021-07-22 18:25:57 +02:00
/* Return the value (as a string) of the requested Data (D) subfield of the Data (D) field of an extended command packet */
2021-08-06 13:06:21 +02:00
Array . prototype . commandPacketDataField = function ( field ) {
2021-07-22 18:25:57 +02:00
let fieldSize = [ ] ;
/* Decode the length of Data {1 - ${length}} (D{1 - ${length}}) subfields */
for ( let index = 20 , i = 0 ; i < field ; i ++ )
2021-08-06 13:06:21 +02:00
fieldSize . push ( this . slice ( index , ( index += 2 ) ) . asciiToHex ( ) ) ;
2021-07-22 18:25:57 +02:00
/* Get the requested field size */
let fieldLength = fieldSize . pop ( ) ;
/* Get the index of the requested field */
let fieldIndex = ( fieldSize . length ) ? fieldSize . reduce ( ( accumulator , currentValue ) => accumulator + currentValue ) + 32 : 32 ;
2021-08-06 13:06:21 +02:00
2021-07-22 18:25:57 +02:00
/* Return the ascii array as a string */
2021-08-06 13:06:21 +02:00
return this . slice ( fieldIndex , fieldIndex + fieldLength ) . asciiToString ( ) ;
} ;
2021-07-22 18:25:57 +02:00
2021-08-06 13:06:21 +02:00
/* Return an array containing the value (as a string) of all the Data (D) subfield of the Data (D) field of an extended command packet */
Array . prototype . commandPacketAllDataFields = function ( ) {
2021-07-22 18:25:57 +02:00
let dataFieldSize = [ ] ;
let index = 20
while ( index < 32 )
2021-08-06 13:06:21 +02:00
dataFieldSize . push ( this . slice ( index , ( index += 2 ) ) . asciiToHex ( ) ) ;
2021-07-22 18:25:57 +02:00
2021-08-06 13:06:21 +02:00
return dataFieldSize . map ( ( element ) => this . slice ( index , ( index += element ) ) . asciiToString ( ) ) ;
2021-07-22 18:25:57 +02:00
}
2021-07-20 15:12:43 +02:00
2021-08-06 13:06:21 +02:00
/* Return the value (as a number) of the Total number (CN) subfield of the Data (D) field of a data packet */
Array . prototype . dataPacketDataFieldGetTotalNumber = function ( ) {
return this . slice ( 0 , 4 ) . asciiToHex ( ) ;
}
2021-07-20 15:12:43 +02:00
2021-08-06 13:06:21 +02:00
/* Return the value (as a number) of the Current number (CN) subfield of the Data (D) field of a data packet */
Array . prototype . dataPacketDataFieldGetCurrentNumber = function ( ) {
return this . slice ( 4 , 8 ) . asciiToHex ( ) ;
}
2021-07-25 21:43:43 +02:00
2021-08-06 13:06:21 +02:00
/* Return the Data (D) subfield of the Data (D) field of a data packet */
Array . prototype . dataPacketDataFieldGetData = function ( ) {
return this . slice ( 8 , this . length ) ;
}
/* ---------------------Packet making--------------------- */
2021-07-25 21:43:43 +02:00
2021-08-06 13:06:21 +02:00
p7 . make = {
/ * C r e a t e a b a s i c ( N o n - E x t e n d e d ) p a c k e t
* Return the packet * /
basicPacket : ( type , subtype ) =>
( [ type , //Type (T)
... subtype . hexToAscii ( 2 ) , //Subtype (ST)
0x30 ] . addP7Checksum ( ) ) , //Extended (EX)
/ * C r e a t e a n E x t e n d e d p a c k e t
* Return the packet * /
extendedPacket : ( type , subtype , dataField ) =>
( [ type ,
... subtype . hexToAscii ( 2 ) ,
0x31 ,
... ( dataField = dataField . encodeDataField ( ) ) . length . hexToAscii ( 4 ) ,
... dataField ] . addP7Checksum ( ) ) ,
/ * C r e a t e a b u f f e r c o n t a i n i n g t h e D a t a ( D ) f i e l d o f a c o m m a n d p a c k e t
* Return the buffer * /
commandPacketDataField : ( datatype , fileSize , commandArguments ) =>
( [ 0x30 , 0x30 , //Overwrite (OW)
... datatype . hexToAscii ( 2 ) , //Data type (DT) ??
... fileSize . hexToAscii ( 8 ) , //File size (FS)
... commandArguments . flatMap ( ( element ) => element . length . hexToAscii ( 2 ) ) , //Size of Data {1..6} (SD{1..6})
... commandArguments . join ( '' ) . toAscii ( ) ] ) , //Data {1..6} (D{1..6})
/ * C r e a t e a b u f f e r c o n t a i n i n g t h e D a t a ( D ) f i e l d o f a d a t a p a c k e t
* Return the buffer * /
dataPacketDataField : ( totalNumber , currentNumber , data ) =>
( [ ... totalNumber . hexToAscii ( 4 ) , //Total number (TN) subfield
... currentNumber . hexToAscii ( 4 ) , //Current number (CN) subfield
... data ] ) , //Data (DD) subfield
} ;
2021-07-25 21:43:43 +02:00
2021-08-06 13:06:21 +02:00
/* ---------------------Packet receiving--------------------- */
p7 . receive = {
packet : function ( ) {
console . log ( "%cReceiving..." , "color: orange" ) ;
2021-07-21 17:13:22 +02:00
2021-08-06 13:06:21 +02:00
var packetInfo = { } ;
2021-07-21 17:13:22 +02:00
2021-08-06 13:06:21 +02:00
return p7 . device . transferIn ( 2 , 64 )
. then ( function receive ( transferInResult ) {
if ( ! transferInResult . data . byteLength ) {
console . log ( 'buffer was empty, retrying' ) ;
return p7 . device . transferIn ( 2 , 64 ) . then ( receive ) ;
}
packetInfo . receiveBuffer = Array . from ( new Uint8Array ( transferInResult . data . buffer ) ) ;
packetInfo . length = 6 ; //Type (T), Subtype (S), Extended (EX) and Checksum (CS) fields
//Set Type (T) field
packetInfo . type = packetInfo . receiveBuffer [ 0 ] ;
//Set Subtype (ST) field
packetInfo . subtype = packetInfo . receiveBuffer . slice ( 1 , 2 ) . asciiToHex ( ) ;
2021-07-25 21:43:43 +02:00
2021-08-06 13:06:21 +02:00
//Set Extended (EX) field
if ( ( packetInfo . extended = ( packetInfo . receiveBuffer [ 3 ] === 0x31 ) ) ) {
console . log ( 'packet is extended' ) ;
//Set Data size (DS) field
packetInfo . dataSize = packetInfo . receiveBuffer . slice ( 4 , 8 ) . asciiToHex ( ) ;
packetInfo . length += packetInfo . dataSize + 4 ; //Data size field
if ( 64 < packetInfo . length )
return p7 . device . transferIn ( 2 , packetInfo . length - 64 )
. then ( ( transferInResult ) => packetInfo . receiveBuffer . push ( ... ( new Uint8Array ( transferInResult . data . buffer ) ) ) ) ;
}
} ) . then ( ( ) => {
if ( packetInfo . extended )
packetInfo . data = packetInfo . receiveBuffer . slice ( 8 , packetInfo . receiveBuffer . length - 2 ) . decodeDataField ( ) ;
//Compute checksum
let checksumError = ( ( packetInfo . checksum = packetInfo . receiveBuffer . slice ( packetInfo . length - 2 , packetInfo . length ) . asciiToHex ( ) ) !== packetInfo . receiveBuffer . slice ( 1 , packetInfo . length - 2 ) . p7Checksum ( ) ) ;
return packetInfo ;
} ) . catch ( ( err ) => {
err . message = "Couldn't receive the packet: " + err . message ;
throw err ;
} ) ;
} ,
data : function ( responsePacketInfo ) {
var data = [ ] ;
return p7 . send . packet ( p7 . make . basicPacket ( p7PacketType . ack , ackSubtype . default ) )
. then ( function receiveData ( responsePacketInfo ) {
if ( responsePacketInfo . type !== p7PacketType . data )
return [ data . flat ( ) , responsePacketInfo ] ;
data . push ( responsePacketInfo . data . dataPacketDataFieldGetData ( ) ) ;
return p7 . send . packet ( p7 . make . basicPacket ( p7PacketType . ack , ackSubtype . default ) ) . then ( receiveData ) ;
} ) ;
}
} ;
2021-07-14 18:31:10 +02:00
2021-07-20 15:12:43 +02:00
/* ---------------------Packet sending--------------------- */
2021-07-14 18:31:10 +02:00
2021-08-06 13:06:21 +02:00
p7 . send = {
packet : function ( buffer ) {
console . log ( "%cSending packet..." , "color: green" ) ;
return p7 . device . transferOut ( 1 , Uint8Array . from ( buffer ) )
. catch ( ( err ) => {
err . message = "Couldn't send the packet: " + err . message ;
throw err ;
} )
. then ( ( transferOutResult ) => p7 . receive . packet ( ) )
. catch ( ( err ) => {
err . message = "Couldn't receive the response packet: " + err . message ;
throw err ;
} ) ;
} ,
/ * S e n d a s i n g l e c o m m a n d
* Return the informations about the response ack packet * /
singleCommand : ( subtype , datatype , fileSize , commandArguments ) =>
p7 . send . packet ( p7 . make . extendedPacket ( p7PacketType . command , subtype , p7 . make . commandPacketDataField ( datatype , fileSize , commandArguments ) ) )
. then ( ( responsePacketInfo ) => {
if ( ! ( responsePacketInfo . type === p7PacketType . ack && responsePacketInfo . subtype === ackSubtype . default ) )
throw new Error ( "The calculator didn't send the expected ack packet!:" +
"\t{Type: " + responsePacketInfo . type +
"\tSubtype: " + responsePacketInfo . subtype + "}" ) ;
return responsePacketInfo ;
} ) ,
/ * S e n d a s i n g l e c o m m a n d r e q u e s t
* Return an array containing the filtered ( with ` callbackFunction ` ) Data ( D ) field of each response command packet * /
singleCommandRoleswap : function ( subtype , datatype , fileSize , commandArguments , callbackFunction ) {
var filteredData = [ ] ;
return p7 . send . singleCommand ( subtype , datatype , fileSize , commandArguments )
. then ( ( ) => p7 . send . packet ( p7 . make . basicPacket ( p7PacketType . roleswap , roleswapSubtype . default ) ) )
. then ( function receiveRequestedCommand ( responsePacketInfo ) {
if ( responsePacketInfo . type !== p7PacketType . command )
return filteredData ;
filteredData . push ( callbackFunction ( responsePacketInfo . receiveBuffer ) ) ;
return p7 . send . packet ( p7 . make . basicPacket ( p7PacketType . ack , ackSubtype . default ) ) . then ( receiveRequestedCommand ) ;
} ) ;
} ,
dataCommand : function ( subtype , datatype , fileSize , commandArguments , data ) {
var currentPacketNumber = 0 ;
var lastPacketSize = data . length & 0xFF ; //Equivalent to data.length % 256, but way faster !
var totalPacketNumber = ( data . length >> 8 ) + ( lastPacketSize !== 0 ) ; //Equivalent to data.length / 256, but way way waaaaaay faster, and return an integer quotient, not a decimal one !!
2021-07-27 17:03:32 +02:00
return p7 . send . singleCommand ( subtype , datatype , fileSize , commandArguments )
2021-08-06 13:06:21 +02:00
. then ( function sendDataPackets ( result ) {
if ( ( currentPacketNumber += 1 ) === totalPacketNumber )
return p7 . send . packet ( p7 . make . extendedPacket ( p7PacketType . data , subtype , p7 . make . dataPacketDataField ( totalPacketNumber , currentPacketNumber , data . slice ( data . length - lastPacketSize , data . length ) ) ) )
return p7 . send . packet ( p7 . make . extendedPacket ( p7PacketType . data , subtype , p7 . make . dataPacketDataField ( totalPacketNumber , currentPacketNumber , data . slice ( ( ( currentPacketNumber - 1 ) << 8 ) , ( currentPacketNumber << 8 ) ) ) ) ) . then ( sendDataPackets ) ;
2021-07-27 17:03:32 +02:00
} ) ;
2021-08-06 13:06:21 +02:00
} ,
dataCommandRoleswap : async function ( subtype , datatype , fileSize , commandArguments , callbackFunction ) {
var filteredData = [ ] ;
return p7 . send . singleCommand ( subtype , datatype , fileSize , commandArguments )
. then ( ( ) => p7 . send . packet ( p7 . make . basicPacket ( p7PacketType . roleswap , roleswapSubtype . default ) ) )
. then ( function receiveRequestedData ( responsePacketInfo ) {
if ( responsePacketInfo . type === p7PacketType . roleswap )
return filteredData ;
let command = responsePacketInfo . receiveBuffer ;
return p7 . receive . data ( )
. then ( ( dataResponse ) => {
filteredData . push ( callbackFunction ( command , dataResponse [ 0 ] ) ) ;
return receiveRequestedData ( dataResponse [ 1 ] ) ;
} ) ;
} ) ;
}
} ;
2021-07-22 18:25:57 +02:00
2021-07-20 15:12:43 +02:00
/* ---------------------Initialization and exiting--------------------- */
2021-07-27 17:03:32 +02:00
/* 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
} ) ;
/ * R e c e i v e a n d s e n d s o m e u s b c o n t r o l m e s s a g e , a s d e f i n e d i n f x R e v e r s e d o c u m e n t a t i o n
*
* 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 ;
2021-07-21 12:27:19 +02:00
2021-07-27 17:03:32 +02:00
try {
2021-07-21 12:27:19 +02:00
transferInResult = await p7 . device . controlTransferIn ( {
2021-07-27 17:03:32 +02:00
requestType : 'standard' ,
recipient : 'device' ,
request : 0x06 , // GET_DESCRIPTOR
value : 0x0100 , // Descriptor Type and Descriptor Index
index : 0x0000
} , 0x12 ) ; // Length
} catch ( err ) {
console . log ( err ) ;
}
2021-07-21 12:27:19 +02:00
2021-07-27 17:03:32 +02:00
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 ) ;
2021-07-14 18:31:10 +02:00
}
2021-07-27 17:03:32 +02:00
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!" ) ;
2021-08-06 13:06:21 +02:00
} ) . then ( ( responsePacketInfo ) => responsePacketInfo . receiveBuffer . extendedAckPacket ( ) ) ) ) ;
2021-07-27 17:03:32 +02:00
2021-07-20 15:12:43 +02:00
/* End the connexion with the calculator */
2021-08-06 13:06:21 +02:00
p7 . exit = function ( ) {
2021-07-14 18:31:10 +02:00
2021-07-20 15:12:43 +02:00
}
2021-07-27 17:03:32 +02:00
} ) ( ) ;