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 { TransmissionInterface } from './TransmissionInterface';
17import { PACKET_FLAG, USB_PACKET_FLAG } from '../common/ConstantType';
18import { USBHead } from '../message/USBHead';
19import { DataMessage } from '../message/DataMessage';
20import { DataListener } from '../hdcclient/DataListener';
21import { PayloadProtect } from '../message/PayloadProtect';
22import { Serialize } from '../common/Serialize';
23import { PayloadHead } from '../message/PayloadHead';
24import { UsbProtocolOption } from '../hdcclient/UsbProtocolOption';
25import { toHex16 } from '../common/BaseConversion';
26import { error, log } from '../../log/Log';
27
28export class DataProcessing {
29  private readonly transmissionChannel: TransmissionInterface;
30  private dataListener: DataListener;
31  public readData = true;
32  private static usbHeadSize: number = 11;
33  private static vCode: number = 0x09;
34  private static checkSum: number = 0;
35
36  constructor(dataListener: DataListener, transmissionChannel: TransmissionInterface) {
37    this.dataListener = dataListener;
38    this.transmissionChannel = transmissionChannel;
39  }
40
41  public async startReadData(): Promise<void> {
42    try {
43      while (this.readData) {
44        let usbHead = await this.readUsbHead();
45        if (usbHead !== null) {
46          let dataSize = usbHead!.dataSize;
47          if (dataSize > 0) {
48            let body = await this.readBody(dataSize);
49            let message = new DataMessage(usbHead, body);
50            this.dataListener.createDataMessage(message);
51          } else {
52            let message = new DataMessage(usbHead);
53            this.dataListener.createDataMessage(message);
54          }
55        } else {
56          log('head is null');
57        }
58      }
59    } catch (e) {
60      let ubsHead = new USBHead([-1, -1], -1, -1, -1);
61      let message = new DataMessage(ubsHead);
62      this.dataListener.createDataMessage(message);
63      error('error', e);
64    }
65  }
66
67  public async readUsbHead(): Promise<USBHead | null> {
68    let res = await this.transmissionChannel.readData(USBHead.getUSBHeadLength());
69    if (res) {
70      let useHead: USBHead = USBHead.parseHeadData(res);
71      return useHead;
72    }
73    return null;
74  }
75
76  public async readBody(dataSize: number): Promise<DataView> {
77    let data = await this.transmissionChannel.readData(dataSize);
78    return data;
79  }
80
81  public async send(
82    sessionId: number,
83    channelId: number,
84    commandFlag: number,
85    data: Uint8Array,
86    dataSize: number
87  ): Promise<boolean> {
88    let protectBuf: PayloadProtect = new PayloadProtect(
89      channelId,
90      commandFlag,
91      DataProcessing.checkSum,
92      DataProcessing.vCode
93    );
94    let pbs = Serialize.serializePayloadProtect(protectBuf);
95    let payloadHead: PayloadHead = new PayloadHead(
96      [PACKET_FLAG.charCodeAt(0), PACKET_FLAG.charCodeAt(1)],
97      [0, 0],
98      1,
99      pbs.byteLength,
100      dataSize
101    );
102    let dataView = payloadHead.getDataView();
103    let playHeadArray = new Uint8Array(dataView.buffer);
104    let finalBufSize = dataView.byteLength + pbs.byteLength + dataSize;
105    let finalBuf = new Uint8Array(finalBufSize);
106    finalBuf.set(playHeadArray);
107    finalBuf.set(pbs, dataView.byteLength);
108    finalBuf.set(data, dataView.byteLength + pbs.byteLength);
109    if (this.transmissionChannel) {
110      let header = this.buildPacketHeader(sessionId, UsbProtocolOption.USB_OPTION_HEADER, finalBufSize);
111      await this.transmissionChannel.writeData(header);
112      await this.transmissionChannel.writeData(finalBuf);
113      return true;
114    } else {
115      this.stopReadData();
116      return false;
117    }
118  }
119
120  private buildPacketHeader(sessionId: number, option: number, dataSize: number): Uint8Array {
121    let head: USBHead = new USBHead(
122      [USB_PACKET_FLAG.charCodeAt(0), USB_PACKET_FLAG.charCodeAt(1)],
123      option,
124      sessionId,
125      dataSize
126    );
127    let dataView = head.getDataView();
128    return new Uint8Array(dataView.buffer);
129  }
130
131  public stopReadData(): void {
132    this.readData = false;
133  }
134}
135