xref: /developtools/hdc/hdc_rust/src/transfer/base.rs (revision cc290419)
1/*
2 * Copyright (C) 2023 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//! base
16#![allow(missing_docs)]
17
18#[cfg(feature = "host")]
19extern crate ylong_runtime_static as ylong_runtime;
20use ylong_runtime::sync::mpsc::BoundedSender;
21use ylong_runtime::task::JoinHandle;
22
23use crate::config::TaskMessage;
24use crate::config::*;
25use crate::serializer;
26use crate::utils;
27#[allow(unused)]
28use crate::utils::hdc_log::*;
29
30use std::io::{self, Error, ErrorKind};
31use std::sync::Arc;
32use ylong_runtime::sync::Mutex;
33
34type BOOL_ = Arc<Mutex<bool>>;
35
36pub struct CheckCompressVersion {}
37impl CheckCompressVersion {
38    pub fn get_instance() -> BOOL_ {
39        static mut CAN_COMPRESS: Option<BOOL_> = Option::None;
40        unsafe {
41            CAN_COMPRESS
42                .get_or_insert_with(|| Arc::new(Mutex::new(false)))
43                .clone()
44        }
45    }
46
47    pub async fn set(check_version: bool) {
48        let arc = Self::get_instance();
49        let mut mutex = arc.lock().await;
50        *mutex = check_version;
51    }
52
53    pub async fn get() -> bool {
54        let arc = Self::get_instance();
55        let mutex = arc.lock().await;
56        *mutex
57    }
58}
59
60pub trait Writer {
61    fn write_all(&self, data: Vec<u8>) -> io::Result<i32>;
62}
63
64pub trait Reader: Send + Sync + 'static {
65    fn read_frame(&self, expected_size: usize) -> io::Result<Vec<u8>>;
66    fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> {
67        Err(utils::error_other("not implemeted".to_string()))
68    }
69    fn process_head(&self) -> Option<JoinHandle<()>> {
70        None
71    }
72}
73
74pub async fn unpack_task_message_lock(
75    rd: &mut dyn Reader,
76    pack_size: u32,
77    tx: BoundedSender<TaskMessage>,
78) -> io::Result<()> {
79    let data = rd.read_frame(pack_size as usize)?;
80    let (head, body) = data.split_at(serializer::HEAD_SIZE);
81    let payload_head = serializer::unpack_payload_head(head.to_vec());
82    match payload_head {
83        Ok(payload_head) => {
84            let expected_head_size = u16::from_be(payload_head.head_size) as usize;
85            let expected_data_size = u32::from_be(payload_head.data_size) as usize;
86
87            if serializer::HEAD_SIZE + expected_head_size + expected_data_size != pack_size as usize
88            {
89                crate::warn!(
90                    "protocol size diff: {pack_size} != {} + {expected_head_size} + {expected_data_size}",
91                    serializer::HEAD_SIZE
92                );
93            }
94
95            if expected_head_size + expected_data_size == 0
96                || expected_head_size + expected_data_size > HDC_BUF_MAX_SIZE
97            {
98                return Err(Error::new(ErrorKind::Other, "Packet size incorrect"));
99            }
100
101            let (protect, payload) = body.split_at(expected_head_size);
102
103            let payload_protect = serializer::unpack_payload_protect(protect.to_vec())?;
104            let channel_id = payload_protect.channel_id;
105
106            let command = match HdcCommand::try_from(payload_protect.command_flag) {
107                Ok(command) => command,
108                Err(_) => {
109                    return Err(Error::new(ErrorKind::Other, "unknown command"));
110                }
111            };
112            let mut remaining = (expected_data_size - payload.len()) as i32;
113            if remaining == 0 {
114                let _ = tx
115                    .send(TaskMessage {
116                        channel_id,
117                        command,
118                        payload: payload.to_vec(),
119                    })
120                    .await;
121            }
122            let mut total_payload = payload.to_vec();
123            while remaining > 0 {
124                let head_result = rd.check_protocol_head();
125                match head_result {
126                    Ok((packet_size, _pkg_index, _session_id)) => {
127                        if let Some(join_handle) = rd.process_head() {
128                            let _ = join_handle.await;
129                        }
130                        if packet_size == 0 {
131                            continue;
132                        }
133                        let mut payload1 = rd.read_frame(packet_size as usize)?;
134                        total_payload.append(&mut payload1);
135                        remaining -= packet_size as i32;
136                        crate::debug!("remaining:{}, packet_size:{}", remaining, packet_size);
137                        if remaining == 0 {
138                            let _ = tx
139                                .send(TaskMessage {
140                                    channel_id,
141                                    command,
142                                    payload: total_payload,
143                                })
144                                .await;
145                            break;
146                        }
147                    }
148                    Err(e) => {
149                        return Err(utils::error_other(format!("check head error: {:?}", e)));
150                    }
151                }
152            }
153
154            let _ = tx
155                .send(TaskMessage {
156                    channel_id,
157                    command: HdcCommand::UartFinish,
158                    payload: vec![],
159                })
160                .await;
161            Ok(())
162        }
163        Err(e) => {
164            Err(utils::error_other(format!("uart unpack_task_message_lock, err:{:?}", e)))
165        }
166    }
167}
168
169pub fn unpack_task_message(
170    rd: &mut dyn Reader,
171    tx: BoundedSender<(TaskMessage, u32, u32)>,
172) -> io::Result<()> {
173    let (pack_size, package_index, session_id) = rd.check_protocol_head()?;
174    if pack_size == 0 {
175        return Ok(());
176    }
177
178    let data = rd.read_frame(pack_size as usize)?;
179    ylong_runtime::spawn(async move {
180        let (head, body) = data.split_at(serializer::HEAD_SIZE);
181        let payload_head = serializer::unpack_payload_head(head.to_vec());
182        match payload_head {
183            Ok(payload_head) => {
184                let expected_head_size = u16::from_be(payload_head.head_size) as usize;
185                let expected_data_size = u32::from_be(payload_head.data_size) as usize;
186
187                if serializer::HEAD_SIZE + expected_head_size + expected_data_size != pack_size as usize {
188                    crate::warn!(
189                        "protocol size diff: {pack_size} != {} + {expected_head_size} + {expected_data_size}",
190                        serializer::HEAD_SIZE
191                    );
192                }
193
194                if expected_head_size + expected_data_size == 0
195                    || expected_head_size + expected_data_size > HDC_BUF_MAX_SIZE
196                {
197                    return Err(Error::new(ErrorKind::Other, "Packet size incorrect"));
198                }
199
200                let (protect, payload) = body.split_at(expected_head_size);
201
202                let payload_protect = serializer::unpack_payload_protect(protect.to_vec())?;
203                let channel_id = payload_protect.channel_id;
204
205                let command = match HdcCommand::try_from(payload_protect.command_flag) {
206                    Ok(command) => command,
207                    Err(_) => {
208                        return Err(Error::new(ErrorKind::Other, "unknown command"));
209                    }
210                };
211
212                let _ = tx
213                    .send((
214                        TaskMessage {
215                            channel_id,
216                            command,
217                            payload: payload.to_vec(),
218                        },
219                        package_index,
220                        session_id,
221                    ))
222                    .await;
223                Ok(())
224            }
225            Err(e) => {
226                Err(utils::error_other(format!("usb unpack_task_message, err:{:?}", e)))
227            }
228        }
229    });
230
231    Ok(())
232}
233