/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Serialize } from '../common/Serialize.js'; import { HdcCommand } from './HdcCommand.js'; import { Utils } from '../common/Utils.js'; import { HANDSHAKE_MESSAGE } from '../common/ConstantType.js'; import { PayloadHead } from '../message/PayloadHead.js'; import { TransmissionInterface } from '../transmission/TransmissionInterface.js'; import { DataProcessing } from '../transmission/DataProcessing.js'; import { DataListener } from './DataListener.js'; import { DataMessage } from '../message/DataMessage.js'; import { SessionHandShake } from '../message/SessionHandShake.js'; import { AuthType } from '../message/AuthType.js'; import { debug, log } from '../../log/Log.js'; import { HdcStream } from './HdcStream.js'; import { toHex16 } from '../common/BaseConversion.js'; export class HdcClient implements DataListener { // @ts-ignore usbDevice: USBDevice | undefined; sessionId: number = 0; private transmissionChannel: TransmissionInterface; public readDataProcessing: DataProcessing; private stream: HdcStream | undefined | null; private hdcStopStream: HdcStream | undefined | null; private cmdStream: number = -1; private stopStream: number = -1; constructor( transmissionChannel: TransmissionInterface, // @ts-ignore usbDevice: USBDevice | undefined ) { this.transmissionChannel = transmissionChannel; this.usbDevice = usbDevice; this.readDataProcessing = new DataProcessing(this, transmissionChannel); } async connectDevice(): Promise { debug('start Connect Device'); this.sessionId = Utils.getSessionId(); log('sessionId is ' + this.sessionId); // @ts-ignore let handShake: SessionHandShake = new SessionHandShake( HANDSHAKE_MESSAGE, AuthType.AUTH_NONE, this.sessionId, // @ts-ignore this.usbDevice.serialNumber, '' ); let hs = Serialize.serializeSessionHandShake(handShake); debug('start Connect hs ', hs); let sendResult = await this.readDataProcessing.send( handShake.sessionId, 0, HdcCommand.CMD_KERNEL_HANDSHAKE, hs, hs.length ); if (sendResult) { let handShake = await this.readDataProcessing.readUsbHead(); let handBody = await this.readDataProcessing.readBody(handShake!.dataSize); if (this.sessionId == handShake!.sessionId) { debug('handShake: ', handShake); let playHeadArray = handBody.buffer.slice(0, PayloadHead.getPayloadHeadLength()); let resultPayloadHead: PayloadHead = PayloadHead.parsePlayHead(new DataView(playHeadArray)); debug('resultPayloadHead is ', resultPayloadHead); let headSize = resultPayloadHead.headSize; let dataSize = resultPayloadHead.dataSize; let resPlayProtectBuffer = handBody.buffer.slice( PayloadHead.getPayloadHeadLength(), PayloadHead.getPayloadHeadLength() + headSize ); debug('PlayProtect is ', resPlayProtectBuffer); let resData = handBody.buffer.slice( PayloadHead.getPayloadHeadLength() + headSize, PayloadHead.getPayloadHeadLength() + headSize + dataSize ); debug('resData is ', resData); this.readDataProcessing.startReadData().then(() => {}); return true; } else { log( 'session is not eq handShake?.sessionId is : ' + handShake?.sessionId + ' now session is ' + this.sessionId ); return false; } } else { return false; } } public async disconnect(): Promise { try { await this.transmissionChannel.close(); this.readDataProcessing.stopReadData(); } catch (e) {} } public bindStream(channel: number, hdcStream: HdcStream) { this.cmdStream = channel; this.stream = hdcStream; } public bindStopStream(channel: number, hdcStopStream: HdcStream) { this.stopStream = channel; this.hdcStopStream = hdcStopStream; } public unbindStream(channel: number): boolean { this.stream = null; return this.stream == null; } public unbindStopStream(channel: number): boolean { this.hdcStopStream = null; return this.hdcStopStream == null; } createDataMessage(data: DataMessage): void { if (this.hdcStopStream && data.getChannelId() == this.stopStream) { this.hdcStopStream.putMessageInQueue(data); } if (this.stream && data.getChannelId() == this.cmdStream) { this.stream.putMessageInQueue(data); } if (data.getChannelId() == -1) { this.stream?.putMessageInQueue(data); this.hdcStopStream?.putMessageInQueue(data); } } }