• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {DataMessage} from "../message/DataMessage.js";
17import {HdcClient} from "./HdcClient.js";
18import {FormatCommand} from "./FormatCommand.js";
19import {HdcCommand} from "./HdcCommand.js";
20import {Utils} from "../common/Utils.js";
21import {AsyncQueue} from "./AsyncQueue.js";
22import {toHex16} from "../common/BaseConversion.js";
23import {PayloadHead} from "../message/PayloadHead.js";
24import {Serialize} from "../common/Serialize.js";
25
26export class HdcStream {
27    private dataMessages: AsyncQueue<DataMessage> = new AsyncQueue<DataMessage>();
28    private readonly channelId: number
29    private interactiveShellMode: boolean = false;
30    private hdcClient: HdcClient;
31    public fileSize: number = -1;
32
33    constructor(hdcClient: HdcClient, isStopCmd:boolean) {
34        this.hdcClient = hdcClient;
35        this.channelId = Utils.getLocalId();
36        if (isStopCmd) {
37            this.hdcClient.bindStopStream(this.channelId, this);
38        } else {
39            this.hdcClient.bindStream(this.channelId, this);
40        }
41    }
42
43    public async DoCommand(cmd: string): Promise<boolean> {
44        let formatCommand;
45        if (this.interactiveShellMode) {
46            formatCommand = new FormatCommand(HdcCommand.CMD_SHELL_DATA, cmd, false);
47        } else {
48            formatCommand = Utils.formatCommand(cmd);
49        }
50        return this.DoCommandRemote(formatCommand);
51    }
52
53    public async DoCommandRemote(command: FormatCommand): Promise<boolean> {
54        switch (command.cmdFlag) {
55            case HdcCommand.CMD_SHELL_INIT:
56            case HdcCommand.CMD_SHELL_DATA:
57            case HdcCommand.CMD_UNITY_EXECUTE:
58            case HdcCommand.CMD_UNITY_TERMINATE:
59            case HdcCommand.CMD_UNITY_REMOUNT:
60            case HdcCommand.CMD_UNITY_REBOOT:
61            case HdcCommand.CMD_UNITY_RUNMODE:
62            case HdcCommand.CMD_UNITY_HILOG: {
63                let textEncoder = new TextEncoder();
64                let data = textEncoder.encode(command.parameters);
65                let sendResult = await this.sendToDaemon(command, data, data.length);
66                if (sendResult) {
67                    if (HdcCommand.CMD_SHELL_INIT == command.cmdFlag) {
68                        this.interactiveShellMode = true;
69                    }
70                }
71                break;
72            }
73            case HdcCommand.CMD_FILE_INIT: {
74                await this.FileRecvCommand(command);
75                break;
76            }
77            case HdcCommand.CMD_FILE_FINISH:
78            case HdcCommand.CMD_KERNEL_CHANNEL_CLOSE: {
79                let dataView = new DataView(new ArrayBuffer(1));
80                if (command.parameters == "0") {
81                    dataView.setUint8(0, 0);
82                } else {
83                    dataView.setUint8(0, 1);
84                }
85                await this.sendToDaemon(command, new Uint8Array(dataView.buffer), 1);
86                break;
87            }
88        }
89        return false;
90    }
91
92    async FileRecvCommand(command: FormatCommand) {
93        let sizeSend = command.parameters.length;
94        let cmdFlag: string = '';
95        let sizeCmdFlag: number = 0;
96        if (HdcCommand.CMD_FILE_INIT == command.cmdFlag) {
97            cmdFlag = "send ";
98            sizeCmdFlag = 5;  // 5: cmdFlag send size
99        }
100        if (!(command.parameters.length > cmdFlag.length)) {
101        } else {
102            let textEncoder = new TextEncoder();
103            let data = textEncoder.encode(command.parameters);
104            let aa = data.slice(5);
105            await this.sendToDaemon(command, aa, aa.length);
106            let dataMessage = await this.getMessage();
107            let playHeadArray = dataMessage.body!.buffer.slice(0, PayloadHead.getPayloadHeadLength())
108            let resultPayloadHead: PayloadHead = PayloadHead.parsePlayHead(new DataView(playHeadArray));
109            let headSize = resultPayloadHead.headSize;
110            let dataSize = resultPayloadHead.dataSize;
111            let resPlayProtectBuffer = dataMessage.body!.buffer.slice(11, 11 + headSize);
112            let payloadProtect = Serialize.parsePayloadProtect(resPlayProtectBuffer);
113            await this.handleCommandFileCheck()
114        }
115    }
116
117    private async handleCommandFileCheck() {
118        let dataMessage = await this.getMessage();
119        let playHeadArray = dataMessage.body!.buffer.slice(0, PayloadHead.getPayloadHeadLength())
120        let resultPayloadHead: PayloadHead = PayloadHead.parsePlayHead(new DataView(playHeadArray));
121        let headSize = resultPayloadHead.headSize;
122        let dataSize = resultPayloadHead.dataSize;
123        let resPlayProtectBuffer = dataMessage.body!.buffer.slice(PayloadHead.getPayloadHeadLength(), PayloadHead.getPayloadHeadLength() + headSize);
124        let payloadProtect = Serialize.parsePayloadProtect(resPlayProtectBuffer);
125        if (payloadProtect.commandFlag == HdcCommand.CMD_FILE_CHECK) {
126            if (dataSize > 0) {
127                let transferConfigBuffer = dataMessage.body!.buffer.slice(PayloadHead.getPayloadHeadLength() + headSize, PayloadHead.getPayloadHeadLength() + headSize + dataSize);
128                let transferConfig = Serialize.parseTransferConfig(transferConfigBuffer);
129                this.fileSize = transferConfig.fileSize;
130            }
131            let fileBegin = new FormatCommand(HdcCommand.CMD_FILE_BEGIN, "", false);
132            await this.sendToDaemon(fileBegin, new Uint8Array(0), 0);
133        }
134    }
135
136    async sendToDaemon(command: FormatCommand, payload: Uint8Array, dataLength: number): Promise<boolean> {
137        return await this.hdcClient.readDataProcessing.send(this.hdcClient.sessionId, this.channelId, command.cmdFlag, payload, dataLength);
138    }
139
140    putMessageInQueue(dataMessage: DataMessage) {
141        this.dataMessages.enqueue(dataMessage);
142    }
143
144    getMessage(): Promise<DataMessage> {
145        return this.dataMessages.dequeue();
146    }
147
148    closeStream() {
149        this.hdcClient.unbindStream(this.channelId);
150    }
151
152    closeStopStream() {
153        this.hdcClient.unbindStopStream(this.channelId);
154    }
155}
156
157
158
159