1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { DataMessage } from '../message/DataMessage'; 17fb726d48Sopenharmony_ciimport { HdcClient } from './HdcClient'; 18fb726d48Sopenharmony_ciimport { FormatCommand } from './FormatCommand'; 19fb726d48Sopenharmony_ciimport { HdcCommand } from './HdcCommand'; 20fb726d48Sopenharmony_ciimport { Utils } from '../common/Utils'; 21fb726d48Sopenharmony_ciimport { AsyncQueue } from './AsyncQueue'; 22fb726d48Sopenharmony_ciimport { PayloadHead } from '../message/PayloadHead'; 23fb726d48Sopenharmony_ciimport { Serialize } from '../common/Serialize'; 24fb726d48Sopenharmony_ci 25fb726d48Sopenharmony_ciexport class HdcStream { 26fb726d48Sopenharmony_ci private dataMessages: AsyncQueue<DataMessage> = new AsyncQueue<DataMessage>(); 27fb726d48Sopenharmony_ci private readonly channelId: number; 28fb726d48Sopenharmony_ci private interactiveShellMode: boolean = false; 29fb726d48Sopenharmony_ci private hdcClient: HdcClient; 30fb726d48Sopenharmony_ci public fileSize: number = -1; 31fb726d48Sopenharmony_ci 32fb726d48Sopenharmony_ci constructor(hdcClient: HdcClient, isStopCmd: boolean) { 33fb726d48Sopenharmony_ci this.hdcClient = hdcClient; 34fb726d48Sopenharmony_ci this.channelId = Utils.getLocalId(); 35fb726d48Sopenharmony_ci this.hdcClient.bindStream(this.channelId, this); 36fb726d48Sopenharmony_ci } 37fb726d48Sopenharmony_ci 38fb726d48Sopenharmony_ci public async DoCommand(cmd: string): Promise<boolean> { 39fb726d48Sopenharmony_ci let formatCommand; 40fb726d48Sopenharmony_ci if (this.interactiveShellMode) { 41fb726d48Sopenharmony_ci formatCommand = new FormatCommand(HdcCommand.CMD_SHELL_DATA, cmd, false); 42fb726d48Sopenharmony_ci } else { 43fb726d48Sopenharmony_ci formatCommand = Utils.formatCommand(cmd); 44fb726d48Sopenharmony_ci } 45fb726d48Sopenharmony_ci return this.DoCommandRemote(formatCommand); 46fb726d48Sopenharmony_ci } 47fb726d48Sopenharmony_ci 48fb726d48Sopenharmony_ci public async DoCommandRemote(command: FormatCommand): Promise<boolean> { 49fb726d48Sopenharmony_ci switch (command.cmdFlag) { 50fb726d48Sopenharmony_ci case HdcCommand.CMD_SHELL_INIT: 51fb726d48Sopenharmony_ci case HdcCommand.CMD_SHELL_DATA: 52fb726d48Sopenharmony_ci case HdcCommand.CMD_UNITY_EXECUTE: 53fb726d48Sopenharmony_ci case HdcCommand.CMD_UNITY_TERMINATE: 54fb726d48Sopenharmony_ci case HdcCommand.CMD_UNITY_REMOUNT: 55fb726d48Sopenharmony_ci case HdcCommand.CMD_UNITY_REBOOT: 56fb726d48Sopenharmony_ci case HdcCommand.CMD_UNITY_RUNMODE: 57fb726d48Sopenharmony_ci case HdcCommand.CMD_UNITY_HILOG: { 58fb726d48Sopenharmony_ci let textEncoder = new TextEncoder(); 59fb726d48Sopenharmony_ci let data = textEncoder.encode(command.parameters); 60fb726d48Sopenharmony_ci let sendResult = await this.sendToDaemon(command, data, data.length); 61fb726d48Sopenharmony_ci if (sendResult) { 62fb726d48Sopenharmony_ci if (HdcCommand.CMD_SHELL_INIT === command.cmdFlag) { 63fb726d48Sopenharmony_ci this.interactiveShellMode = true; 64fb726d48Sopenharmony_ci } 65fb726d48Sopenharmony_ci } 66fb726d48Sopenharmony_ci break; 67fb726d48Sopenharmony_ci } 68fb726d48Sopenharmony_ci case HdcCommand.CMD_FILE_INIT: { 69fb726d48Sopenharmony_ci await this.FileRecvCommand(command); 70fb726d48Sopenharmony_ci break; 71fb726d48Sopenharmony_ci } 72fb726d48Sopenharmony_ci case HdcCommand.CMD_FILE_FINISH: 73fb726d48Sopenharmony_ci case HdcCommand.CMD_KERNEL_CHANNEL_CLOSE: { 74fb726d48Sopenharmony_ci let dataView = new DataView(new ArrayBuffer(1)); 75fb726d48Sopenharmony_ci if (command.parameters === '0') { 76fb726d48Sopenharmony_ci dataView.setUint8(0, 0); 77fb726d48Sopenharmony_ci } else { 78fb726d48Sopenharmony_ci dataView.setUint8(0, 1); 79fb726d48Sopenharmony_ci } 80fb726d48Sopenharmony_ci await this.sendToDaemon(command, new Uint8Array(dataView.buffer), 1); 81fb726d48Sopenharmony_ci break; 82fb726d48Sopenharmony_ci } 83fb726d48Sopenharmony_ci } 84fb726d48Sopenharmony_ci return false; 85fb726d48Sopenharmony_ci } 86fb726d48Sopenharmony_ci 87fb726d48Sopenharmony_ci async FileRecvCommand(command: FormatCommand): Promise<void> { 88fb726d48Sopenharmony_ci let cmdFlag: string = ''; 89fb726d48Sopenharmony_ci let sizeCmdFlag: number = 0; 90fb726d48Sopenharmony_ci if (HdcCommand.CMD_FILE_INIT === command.cmdFlag) { 91fb726d48Sopenharmony_ci cmdFlag = 'send '; 92fb726d48Sopenharmony_ci sizeCmdFlag = 5; // 5: cmdFlag send size 93fb726d48Sopenharmony_ci } 94fb726d48Sopenharmony_ci if (!(command.parameters.length > cmdFlag.length)) { 95fb726d48Sopenharmony_ci } else { 96fb726d48Sopenharmony_ci let textEncoder = new TextEncoder(); 97fb726d48Sopenharmony_ci let data = textEncoder.encode(command.parameters); 98fb726d48Sopenharmony_ci let aa = data.slice(5); 99fb726d48Sopenharmony_ci await this.sendToDaemon(command, aa, aa.length); 100fb726d48Sopenharmony_ci let fileRecvDataMessage = await this.getMessage(); 101fb726d48Sopenharmony_ci let fileRecvPlayHeadArray = fileRecvDataMessage.body!.buffer.slice(0, PayloadHead.getPayloadHeadLength()); 102fb726d48Sopenharmony_ci let fileRecvResultPayloadHead: PayloadHead = PayloadHead.parsePlayHead(new DataView(fileRecvPlayHeadArray)); 103fb726d48Sopenharmony_ci let fileRecvHeadSize = fileRecvResultPayloadHead.headSize; 104fb726d48Sopenharmony_ci let resPlayProtectBuffer = fileRecvDataMessage.body!.buffer.slice(11, 11 + fileRecvHeadSize); 105fb726d48Sopenharmony_ci Serialize.parsePayloadProtect(resPlayProtectBuffer); 106fb726d48Sopenharmony_ci await this.handleCommandFileCheck(); 107fb726d48Sopenharmony_ci } 108fb726d48Sopenharmony_ci } 109fb726d48Sopenharmony_ci 110fb726d48Sopenharmony_ci private async handleCommandFileCheck(): Promise<void> { 111fb726d48Sopenharmony_ci let fileCheckDataMessage = await this.getMessage(); 112fb726d48Sopenharmony_ci let fileCheckPlayHeadArray = fileCheckDataMessage.body!.buffer.slice(0, PayloadHead.getPayloadHeadLength()); 113fb726d48Sopenharmony_ci let fileCheckResultPayloadHead: PayloadHead = PayloadHead.parsePlayHead(new DataView(fileCheckPlayHeadArray)); 114fb726d48Sopenharmony_ci let fileCheckHeadSize = fileCheckResultPayloadHead.headSize; 115fb726d48Sopenharmony_ci let fileCheckDataSize = fileCheckResultPayloadHead.dataSize; 116fb726d48Sopenharmony_ci let fileCheckResPlayProtectBuffer = fileCheckDataMessage.body!.buffer.slice( 117fb726d48Sopenharmony_ci PayloadHead.getPayloadHeadLength(), 118fb726d48Sopenharmony_ci PayloadHead.getPayloadHeadLength() + fileCheckHeadSize 119fb726d48Sopenharmony_ci ); 120fb726d48Sopenharmony_ci let fileCheckPayloadProtect = Serialize.parsePayloadProtect(fileCheckResPlayProtectBuffer); 121fb726d48Sopenharmony_ci if (fileCheckPayloadProtect.commandFlag === HdcCommand.CMD_FILE_CHECK) { 122fb726d48Sopenharmony_ci if (fileCheckDataSize > 0) { 123fb726d48Sopenharmony_ci let fileCheckTransferConfigBuffer = fileCheckDataMessage.body!.buffer.slice( 124fb726d48Sopenharmony_ci PayloadHead.getPayloadHeadLength() + fileCheckHeadSize, 125fb726d48Sopenharmony_ci PayloadHead.getPayloadHeadLength() + fileCheckHeadSize + fileCheckDataSize 126fb726d48Sopenharmony_ci ); 127fb726d48Sopenharmony_ci let fileCheckTransferConfig = Serialize.parseTransferConfig(fileCheckTransferConfigBuffer); 128fb726d48Sopenharmony_ci this.fileSize = fileCheckTransferConfig.fileSize; 129fb726d48Sopenharmony_ci } 130fb726d48Sopenharmony_ci let fileBegin = new FormatCommand(HdcCommand.CMD_FILE_BEGIN, '', false); 131fb726d48Sopenharmony_ci await this.sendToDaemon(fileBegin, new Uint8Array(0), 0); 132fb726d48Sopenharmony_ci } 133fb726d48Sopenharmony_ci } 134fb726d48Sopenharmony_ci 135fb726d48Sopenharmony_ci async sendToDaemon(command: FormatCommand, payload: Uint8Array, dataLength: number): Promise<boolean> { 136fb726d48Sopenharmony_ci return await this.hdcClient.readDataProcessing.send( 137fb726d48Sopenharmony_ci this.hdcClient.sessionId, 138fb726d48Sopenharmony_ci this.channelId, 139fb726d48Sopenharmony_ci command.cmdFlag, 140fb726d48Sopenharmony_ci payload, 141fb726d48Sopenharmony_ci dataLength 142fb726d48Sopenharmony_ci ); 143fb726d48Sopenharmony_ci } 144fb726d48Sopenharmony_ci 145fb726d48Sopenharmony_ci putMessageInQueue(dataMessage: DataMessage): void { 146fb726d48Sopenharmony_ci this.dataMessages.enqueue(dataMessage); 147fb726d48Sopenharmony_ci } 148fb726d48Sopenharmony_ci 149fb726d48Sopenharmony_ci getMessage(): Promise<DataMessage> { 150fb726d48Sopenharmony_ci return this.dataMessages.dequeue(); 151fb726d48Sopenharmony_ci } 152fb726d48Sopenharmony_ci 153fb726d48Sopenharmony_ci async closeStream(): Promise<void> { 154fb726d48Sopenharmony_ci this.hdcClient.unbindStream(this.channelId); 155fb726d48Sopenharmony_ci } 156fb726d48Sopenharmony_ci} 157