1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {Serialize} from "../common/Serialize.js"; 17import {HdcCommand} from "./HdcCommand.js"; 18import {Utils} from "../common/Utils.js"; 19import {HANDSHAKE_MESSAGE} from "../common/ConstantType.js"; 20import {PayloadHead} from "../message/PayloadHead.js"; 21import {TransmissionInterface} from "../transmission/TransmissionInterface.js"; 22import {DataProcessing} from "../transmission/DataProcessing.js"; 23import {DataListener} from "./DataListener.js"; 24import {DataMessage} from "../message/DataMessage.js"; 25import {SessionHandShake} from "../message/SessionHandShake.js"; 26import {AuthType} from "../message/AuthType.js"; 27import {debug, log} from "../../log/Log.js"; 28import {HdcStream} from "./HdcStream.js"; 29import {toHex16} from "../common/BaseConversion.js"; 30 31export class HdcClient implements DataListener { 32 usbDevice: USBDevice | undefined; 33 sessionId: number = 0; 34 private transmissionChannel: TransmissionInterface; 35 public readDataProcessing: DataProcessing; 36 private stream: HdcStream | undefined | null; 37 private hdcStopStream: HdcStream | undefined | null; 38 private cmdStream: number = -1; 39 private stopStream: number = -1; 40 41 constructor(transmissionChannel: TransmissionInterface, usbDevice: USBDevice | undefined) { 42 this.transmissionChannel = transmissionChannel; 43 this.usbDevice = usbDevice; 44 this.readDataProcessing = new DataProcessing(this, transmissionChannel); 45 } 46 47 async connectDevice(): Promise<boolean> { 48 debug("start Connect Device") 49 this.sessionId = Utils.getSessionId(); 50 log("sessionId is " + this.sessionId) 51 // @ts-ignore 52 let handShake: SessionHandShake = new SessionHandShake(HANDSHAKE_MESSAGE, AuthType.AUTH_NONE, this.sessionId, this.usbDevice.serialNumber, ""); 53 let hs = Serialize.serializeSessionHandShake(handShake); 54 debug("start Connect hs ", hs) 55 let sendResult = await this.readDataProcessing.send(handShake.sessionId, 0, HdcCommand.CMD_KERNEL_HANDSHAKE, hs, hs.length); 56 if (sendResult) { 57 let handShake = await this.readDataProcessing.readUsbHead(); 58 let handBody = await this.readDataProcessing.readBody(handShake!.dataSize); 59 if (this.sessionId == handShake!.sessionId) { 60 debug("handShake: ", handShake); 61 let playHeadArray = handBody.buffer.slice(0, PayloadHead.getPayloadHeadLength()) 62 let resultPayloadHead: PayloadHead = PayloadHead.parsePlayHead(new DataView(playHeadArray)); 63 debug("resultPayloadHead is ", resultPayloadHead); 64 let headSize = resultPayloadHead.headSize; 65 let dataSize = resultPayloadHead.dataSize; 66 let resPlayProtectBuffer = handBody.buffer.slice(PayloadHead.getPayloadHeadLength(), PayloadHead.getPayloadHeadLength() + headSize); 67 debug("PlayProtect is ", resPlayProtectBuffer); 68 let resData = handBody.buffer.slice(PayloadHead.getPayloadHeadLength() + headSize, PayloadHead.getPayloadHeadLength() + headSize + dataSize); 69 debug("resData is ", resData); 70 this.readDataProcessing.startReadData().then(() => { 71 }); 72 return true; 73 } else { 74 log("session is not eq handShake?.sessionId is : " + handShake?.sessionId + " now session is " + this.sessionId) 75 return false; 76 } 77 } else { 78 return false; 79 } 80 } 81 82 public async disconnect(): Promise<void> { 83 await this.transmissionChannel.close(); 84 this.readDataProcessing.stopReadData(); 85 } 86 87 public bindStream(channel: number, hdcStream: HdcStream) { 88 this.cmdStream = channel; 89 this.stream = hdcStream; 90 } 91 92 public bindStopStream(channel: number, hdcStopStream: HdcStream) { 93 this.stopStream = channel; 94 this.hdcStopStream = hdcStopStream; 95 } 96 97 public unbindStream(channel: number): boolean { 98 this.stream = null; 99 return this.stream == null; 100 } 101 102 public unbindStopStream(channel: number): boolean { 103 this.hdcStopStream = null; 104 return this.hdcStopStream == null; 105 } 106 107 createDataMessage(data: DataMessage): void { 108 if (this.hdcStopStream && data.getChannelId() == this.stopStream) { 109 this.hdcStopStream.putMessageInQueue(data); 110 } 111 if (this.stream && data.getChannelId() == this.cmdStream) { 112 this.stream.putMessageInQueue(data); 113 } 114 if (data.getChannelId() == -1) { 115 this.stream?.putMessageInQueue(data); 116 this.hdcStopStream?.putMessageInQueue(data); 117 } 118 } 119} 120 121