import isNil from 'lodash/isNil' ; import isEmpty from 'lodash/isEmpty' ; import { delay } from '../../utils' ; import Transport from '../../transport' ; import { MCU_FINISH_CODE , COMMAND_FINISH_CODE , PACKET_DATA_SIZE } from '../constants' ; import { byteArrayToHex , hexToByteArray } from './utils' ; class param { Transport } transport param { boolean } isFinish export default class PeripheralRequest { private transport : Transport ; private isFinish = true ; constructor ( transport ) { this . transport = transport ; } param { number [ ] } packets returns private async sendDataToCard ( packets ) { for ( let pivot = 0 ; pivot * PACKET_DATA_SIZE < packets . length ; pivot += 1 ) { const from = pivot * PACKET_DATA_SIZE ; const to = from + PACKET_DATA_SIZE ; const data = packets . slice ( from , to ) ; console . debug ( '_sendDataToCard data' , data ) ; await this . transport . sendDataToCard ( [ pivot + 1 , data . length , ... data ] ) ; } } param { string } prev returns { Promise < string > } private readDataFromCard = async ( ) : Promise < string > => { let depot = '' ; while ( true ) { const resultDataRaw = await this . transport . readDataFromCard ( ) ; const resultData = byteArrayToHex ( resultDataRaw ) ; console . debug ( '_readDataFromCard resultData' , resultData ) ; if ( resultData === MCU_FINISH_CODE ) { return depot ; } depot += resultData . slice ( 4 ) ; } } ; returns { Promise < string > } private checkCardStatus = async ( ) => { while ( true ) { if ( this . isFinish ) return '' ; const statusCode = await this . transport . checkCardStatus ( ) ; console . debug ( '_checkCardStatus statusCode' , statusCode ) ; if ( statusCode === COMMAND_FINISH_CODE ) { this . isFinish = true ; return this . readDataFromCard ( ) ; } await delay ( 1000 ) ; } } ; param { string } command param { string } packets returns { Promise < string > } sendAPDU = async ( command , packets ) : Promise < string > => { const bytesCommand = hexToByteArray ( command ) ; console . debug ( 'sendCommandToCard statusCode' , command ) ; this . isFinish = false ; await this . transport . sendCommandToCard ( bytesCommand ) ; const bytesPackets = hexToByteArray ( packets ) ; if ( ! isNil ( bytesPackets ) && ! isEmpty ( bytesPackets ) ) { await this . sendDataToCard ( bytesPackets ) ; } return this . checkCardStatus ( ) ; } ; }