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