1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci//! tcp
16cc290419Sopenharmony_ci#![allow(missing_docs)]
17cc290419Sopenharmony_ci
18cc290419Sopenharmony_ciuse crate::config::*;
19cc290419Sopenharmony_ciuse crate::serializer;
20cc290419Sopenharmony_ci#[allow(unused)]
21cc290419Sopenharmony_ciuse crate::utils::hdc_log::*;
22cc290419Sopenharmony_ci
23cc290419Sopenharmony_ciuse std::io::{self, Error, ErrorKind};
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_ci#[cfg(feature = "host")]
26cc290419Sopenharmony_ciextern crate ylong_runtime_static as ylong_runtime;
27cc290419Sopenharmony_ciuse ylong_runtime::io::AsyncReadExt;
28cc290419Sopenharmony_ciuse ylong_runtime::net::SplitReadHalf;
29cc290419Sopenharmony_ci
30cc290419Sopenharmony_ciasync fn read_frame(rd: &mut SplitReadHalf, expected_size: usize) -> io::Result<Vec<u8>> {
31cc290419Sopenharmony_ci    if expected_size == 0 {
32cc290419Sopenharmony_ci        return Ok(vec![]);
33cc290419Sopenharmony_ci    }
34cc290419Sopenharmony_ci    let mut data = vec![0_u8; expected_size];
35cc290419Sopenharmony_ci    let mut index: usize = 0;
36cc290419Sopenharmony_ci    while index < expected_size {
37cc290419Sopenharmony_ci        crate::trace!("before read {index} / {expected_size}");
38cc290419Sopenharmony_ci        match rd.read(&mut data[index..]).await {
39cc290419Sopenharmony_ci            Ok(recv_size) => {
40cc290419Sopenharmony_ci                crate::trace!("after read {recv_size}");
41cc290419Sopenharmony_ci                if recv_size == 0 {
42cc290419Sopenharmony_ci                    crate::debug!("peer shutdown");
43cc290419Sopenharmony_ci                    return Err(Error::new(ErrorKind::ConnectionAborted, "peer shutdown"));
44cc290419Sopenharmony_ci                }
45cc290419Sopenharmony_ci                index += recv_size;
46cc290419Sopenharmony_ci            }
47cc290419Sopenharmony_ci            Err(e) => {
48cc290419Sopenharmony_ci                crate::warn!("read tcp failed: {}", e.to_string());
49cc290419Sopenharmony_ci                return Err(Error::new(ErrorKind::Other, "read tcp failed"));
50cc290419Sopenharmony_ci            }
51cc290419Sopenharmony_ci        }
52cc290419Sopenharmony_ci    }
53cc290419Sopenharmony_ci    Ok(data)
54cc290419Sopenharmony_ci}
55cc290419Sopenharmony_ci
56cc290419Sopenharmony_cipub async fn unpack_task_message(rd: &mut SplitReadHalf) -> io::Result<TaskMessage> {
57cc290419Sopenharmony_ci    let data = read_frame(rd, serializer::HEAD_SIZE).await?;
58cc290419Sopenharmony_ci    let payload_head = serializer::unpack_payload_head(data)?;
59cc290419Sopenharmony_ci    crate::trace!("get payload_head: {:?}", payload_head);
60cc290419Sopenharmony_ci
61cc290419Sopenharmony_ci    let expected_head_size = u16::from_be(payload_head.head_size) as usize;
62cc290419Sopenharmony_ci    let expected_data_size = u32::from_be(payload_head.data_size) as usize;
63cc290419Sopenharmony_ci    if expected_head_size + expected_data_size == 0
64cc290419Sopenharmony_ci        || expected_head_size + expected_data_size > HDC_BUF_MAX_SIZE
65cc290419Sopenharmony_ci    {
66cc290419Sopenharmony_ci        return Err(Error::new(ErrorKind::Other, "Packet size incorrect"));
67cc290419Sopenharmony_ci    }
68cc290419Sopenharmony_ci
69cc290419Sopenharmony_ci    let data = read_frame(rd, expected_head_size).await?;
70cc290419Sopenharmony_ci    let payload_protect = serializer::unpack_payload_protect(data)?;
71cc290419Sopenharmony_ci    crate::trace!("get payload_protect: {:?}", payload_protect);
72cc290419Sopenharmony_ci    let channel_id = payload_protect.channel_id;
73cc290419Sopenharmony_ci
74cc290419Sopenharmony_ci    let command = match HdcCommand::try_from(payload_protect.command_flag) {
75cc290419Sopenharmony_ci        Ok(command) => command,
76cc290419Sopenharmony_ci        Err(_) => {
77cc290419Sopenharmony_ci            return Err(Error::new(ErrorKind::Other, "unknown command"));
78cc290419Sopenharmony_ci        }
79cc290419Sopenharmony_ci    };
80cc290419Sopenharmony_ci
81cc290419Sopenharmony_ci    let payload = read_frame(rd, expected_data_size).await?;
82cc290419Sopenharmony_ci    Ok(TaskMessage {
83cc290419Sopenharmony_ci        channel_id,
84cc290419Sopenharmony_ci        command,
85cc290419Sopenharmony_ci        payload,
86cc290419Sopenharmony_ci    })
87cc290419Sopenharmony_ci}
88cc290419Sopenharmony_ci
89cc290419Sopenharmony_cipub async fn recv_channel_message(rd: &mut SplitReadHalf) -> io::Result<Vec<u8>> {
90cc290419Sopenharmony_ci    let data = read_frame(rd, 4).await?;
91cc290419Sopenharmony_ci    let Ok(data) = data.try_into() else {
92cc290419Sopenharmony_ci        return Err(Error::new(
93cc290419Sopenharmony_ci            ErrorKind::Other,
94cc290419Sopenharmony_ci            "Data forced conversion failed",
95cc290419Sopenharmony_ci        ));
96cc290419Sopenharmony_ci    };
97cc290419Sopenharmony_ci    let expected_size = u32::from_be_bytes(data);
98cc290419Sopenharmony_ci    read_frame(rd, expected_size as usize).await
99cc290419Sopenharmony_ci}
100