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_ciuse hdc::common::base::Base;
16cc290419Sopenharmony_ciuse hdc::common::filemanager::FileManager;
17cc290419Sopenharmony_ciuse hdc::common::hdcfile;
18cc290419Sopenharmony_ciuse hdc::common::hdctransfer::{self, HdcTransferBase};
19cc290419Sopenharmony_ciuse hdc::config::HdcCommand;
20cc290419Sopenharmony_ciuse hdc::config::TaskMessage;
21cc290419Sopenharmony_ciuse hdc::config::TRANSFER_FUNC_NAME;
22cc290419Sopenharmony_ciuse hdc::config::{self, INSTALL_TAR_MAX_CNT};
23cc290419Sopenharmony_ciuse hdc::serializer::serialize::Serialization;
24cc290419Sopenharmony_ciuse hdc::transfer;
25cc290419Sopenharmony_ciuse hdc::transfer::EchoLevel;
26cc290419Sopenharmony_ciuse hdc::utils;
27cc290419Sopenharmony_ciuse std::collections::HashMap;
28cc290419Sopenharmony_ciuse std::path::PathBuf;
29cc290419Sopenharmony_ciuse std::sync::Arc;
30cc290419Sopenharmony_ciuse ylong_runtime::sync::Mutex;
31cc290419Sopenharmony_ci#[cfg(feature = "host")]
32cc290419Sopenharmony_ciextern crate ylong_runtime_static as ylong_runtime;
33cc290419Sopenharmony_ciuse hdc::tar::compress::Compress;
34cc290419Sopenharmony_ci
35cc290419Sopenharmony_cipub struct HostAppTask {
36cc290419Sopenharmony_ci    pub transfer: HdcTransferBase,
37cc290419Sopenharmony_ci    pub printed_msg_len: usize,
38cc290419Sopenharmony_ci}
39cc290419Sopenharmony_ci
40cc290419Sopenharmony_ciimpl HostAppTask {
41cc290419Sopenharmony_ci    ///  complie failed ,associated function `new` is never used
42cc290419Sopenharmony_ci    pub fn new(_session_id: u32, _channel_id: u32) -> Self {
43cc290419Sopenharmony_ci        Self {
44cc290419Sopenharmony_ci            transfer: HdcTransferBase::new(_session_id, _channel_id),
45cc290419Sopenharmony_ci            printed_msg_len: 0,
46cc290419Sopenharmony_ci        }
47cc290419Sopenharmony_ci    }
48cc290419Sopenharmony_ci}
49cc290419Sopenharmony_ci
50cc290419Sopenharmony_citype HostAppTask_ = Arc<Mutex<HostAppTask>>;
51cc290419Sopenharmony_citype HostAppTaskMap_ = Arc<Mutex<HashMap<(u32, u32), HostAppTask_>>>;
52cc290419Sopenharmony_ci
53cc290419Sopenharmony_cipub struct HostAppTaskMap {}
54cc290419Sopenharmony_ciimpl HostAppTaskMap {
55cc290419Sopenharmony_ci    fn get_instance() -> HostAppTaskMap_ {
56cc290419Sopenharmony_ci        static mut HOSTAPPTASKMAP: Option<HostAppTaskMap_> = None;
57cc290419Sopenharmony_ci        unsafe {
58cc290419Sopenharmony_ci            HOSTAPPTASKMAP
59cc290419Sopenharmony_ci                .get_or_insert_with(|| Arc::new(Mutex::new(HashMap::new())))
60cc290419Sopenharmony_ci                .clone()
61cc290419Sopenharmony_ci        }
62cc290419Sopenharmony_ci    }
63cc290419Sopenharmony_ci
64cc290419Sopenharmony_ci    pub async fn put(session_id: u32, channel_id: u32, host_app_task: HostAppTask) {
65cc290419Sopenharmony_ci        let arc_map = Self::get_instance();
66cc290419Sopenharmony_ci        let mut map = arc_map.lock().await;
67cc290419Sopenharmony_ci        map.insert(
68cc290419Sopenharmony_ci            (session_id, channel_id),
69cc290419Sopenharmony_ci            Arc::new(Mutex::new(host_app_task)),
70cc290419Sopenharmony_ci        );
71cc290419Sopenharmony_ci    }
72cc290419Sopenharmony_ci
73cc290419Sopenharmony_ci    pub async fn exist(session_id: u32, channel_id: u32) -> Result<bool, ()> {
74cc290419Sopenharmony_ci        let arc_map = Self::get_instance();
75cc290419Sopenharmony_ci        let map = arc_map.lock().await;
76cc290419Sopenharmony_ci        Ok(map.contains_key(&(session_id, channel_id)))
77cc290419Sopenharmony_ci    }
78cc290419Sopenharmony_ci
79cc290419Sopenharmony_ci    pub async fn remove(session_id: u32, channel_id: u32) -> Option<HostAppTask_> {
80cc290419Sopenharmony_ci        let arc_map = Self::get_instance();
81cc290419Sopenharmony_ci        let mut map = arc_map.lock().await;
82cc290419Sopenharmony_ci        map.remove(&(session_id, channel_id))
83cc290419Sopenharmony_ci    }
84cc290419Sopenharmony_ci
85cc290419Sopenharmony_ci    pub async fn get(session_id: u32, channel_id: u32) -> Option<HostAppTask_> {
86cc290419Sopenharmony_ci        let arc_map = Self::get_instance();
87cc290419Sopenharmony_ci        let map = arc_map.lock().await;
88cc290419Sopenharmony_ci        let Some(arc_task) = map.get(&(session_id, channel_id)) else {
89cc290419Sopenharmony_ci            return None;
90cc290419Sopenharmony_ci        };
91cc290419Sopenharmony_ci        Some(arc_task.clone())
92cc290419Sopenharmony_ci    }
93cc290419Sopenharmony_ci}
94cc290419Sopenharmony_ci
95cc290419Sopenharmony_ciasync fn check_install_continue(
96cc290419Sopenharmony_ci    session_id: u32,
97cc290419Sopenharmony_ci    channel_id: u32,
98cc290419Sopenharmony_ci    mode_type: config::AppModeType,
99cc290419Sopenharmony_ci    str: String,
100cc290419Sopenharmony_ci) -> bool {
101cc290419Sopenharmony_ci    let mode_desc = match mode_type {
102cc290419Sopenharmony_ci        config::AppModeType::Install => String::from("App install"),
103cc290419Sopenharmony_ci        config::AppModeType::UnInstall => String::from("App uninstall"),
104cc290419Sopenharmony_ci    };
105cc290419Sopenharmony_ci    let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else {
106cc290419Sopenharmony_ci        hdc::error!("Get host app task failed");
107cc290419Sopenharmony_ci        return false;
108cc290419Sopenharmony_ci    };
109cc290419Sopenharmony_ci    let mut task = arc_task.lock().await;
110cc290419Sopenharmony_ci    let msg = str[task.printed_msg_len..].to_owned();
111cc290419Sopenharmony_ci    let local_path = if !task.transfer.local_tar_raw_path.is_empty() {
112cc290419Sopenharmony_ci        &task.transfer.local_tar_raw_path
113cc290419Sopenharmony_ci    } else {
114cc290419Sopenharmony_ci        &task.transfer.local_path
115cc290419Sopenharmony_ci    };
116cc290419Sopenharmony_ci    let message =
117cc290419Sopenharmony_ci        format!("{} path:{}, queuesize:{}, msg:{}", mode_desc, local_path, task.transfer.task_queue.len(), msg);
118cc290419Sopenharmony_ci    hdc::info!("{message}");
119cc290419Sopenharmony_ci    task.printed_msg_len = str.len();
120cc290419Sopenharmony_ci    let _ = transfer::send_channel_msg(channel_id, EchoLevel::INFO, message).await;
121cc290419Sopenharmony_ci    if task.transfer.task_queue.is_empty() {
122cc290419Sopenharmony_ci        let _ = transfer::send_channel_msg(channel_id, EchoLevel::INFO, String::from("AppMod finish")).await;
123cc290419Sopenharmony_ci        task_finish(session_id, channel_id).await;
124cc290419Sopenharmony_ci        hdctransfer::close_channel(channel_id).await;
125cc290419Sopenharmony_ci        return false;
126cc290419Sopenharmony_ci    }
127cc290419Sopenharmony_ci    drop(task);
128cc290419Sopenharmony_ci    if let Err(err_msg) = install_single(session_id, channel_id).await {
129cc290419Sopenharmony_ci        let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await;
130cc290419Sopenharmony_ci        task_finish(session_id, channel_id).await;
131cc290419Sopenharmony_ci        return false;
132cc290419Sopenharmony_ci    }
133cc290419Sopenharmony_ci    put_app_check(session_id, channel_id).await;
134cc290419Sopenharmony_ci    true
135cc290419Sopenharmony_ci}
136cc290419Sopenharmony_ci
137cc290419Sopenharmony_ciasync fn do_app_uninstall(session_id: u32, channel_id: u32, payload: Vec<u8>) {
138cc290419Sopenharmony_ci    hdc::info!("send HdcCommand::AppUninstall");
139cc290419Sopenharmony_ci    let app_uninstall_message = TaskMessage { channel_id, command: HdcCommand::AppUninstall, payload };
140cc290419Sopenharmony_ci    transfer::put(session_id, app_uninstall_message).await;
141cc290419Sopenharmony_ci}
142cc290419Sopenharmony_ci
143cc290419Sopenharmony_ciasync fn do_app_finish(session_id: u32, channel_id: u32, payload: &[u8]) -> bool {
144cc290419Sopenharmony_ci    let mode = config::AppModeType::try_from(payload[0]);
145cc290419Sopenharmony_ci    if let Ok(mode_type) = mode {
146cc290419Sopenharmony_ci        let str = match String::from_utf8(payload[2..].to_vec()) {
147cc290419Sopenharmony_ci            Ok(str) => str,
148cc290419Sopenharmony_ci            Err(err) => {
149cc290419Sopenharmony_ci                hdc::error!("do_app_finish from_utf8 error, {err}");
150cc290419Sopenharmony_ci                return false;
151cc290419Sopenharmony_ci            }
152cc290419Sopenharmony_ci        };
153cc290419Sopenharmony_ci        return check_install_continue(session_id, channel_id, mode_type, str).await;
154cc290419Sopenharmony_ci    }
155cc290419Sopenharmony_ci    false
156cc290419Sopenharmony_ci}
157cc290419Sopenharmony_ci
158cc290419Sopenharmony_cifn dir_to_tar(dir_path: PathBuf) -> Result<String, String> {
159cc290419Sopenharmony_ci    let mut compress = Compress::new();
160cc290419Sopenharmony_ci    compress.updata_prefix(dir_path.clone());
161cc290419Sopenharmony_ci    if let Err(err) = compress.add_path(&dir_path) {
162cc290419Sopenharmony_ci        return Err(format!("Package as tar and add path error, {err}"));
163cc290419Sopenharmony_ci    }
164cc290419Sopenharmony_ci    compress.updata_max_count(INSTALL_TAR_MAX_CNT);
165cc290419Sopenharmony_ci
166cc290419Sopenharmony_ci    let tar_name = utils::get_pseudo_random_u32().to_string() + ".tar";
167cc290419Sopenharmony_ci    let tar_path = std::env::temp_dir().join(tar_name);
168cc290419Sopenharmony_ci    match compress.compress(tar_path.clone()) {
169cc290419Sopenharmony_ci        Ok(_) => Ok(tar_path.display().to_string()),
170cc290419Sopenharmony_ci        Err(err) => Err(format!("compress {} fial, {}", tar_path.display(), err)),
171cc290419Sopenharmony_ci    }
172cc290419Sopenharmony_ci}
173cc290419Sopenharmony_ci
174cc290419Sopenharmony_ciasync fn task_finish(session_id: u32, channel_id: u32) {
175cc290419Sopenharmony_ci    HostAppTaskMap::remove(session_id, channel_id).await;
176cc290419Sopenharmony_ci    hdctransfer::transfer_task_finish(channel_id, session_id).await
177cc290419Sopenharmony_ci}
178cc290419Sopenharmony_ci
179cc290419Sopenharmony_ciasync fn put_app_check(session_id: u32, channel_id: u32) {
180cc290419Sopenharmony_ci    let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else {
181cc290419Sopenharmony_ci        hdc::error!("Get host app task failed");
182cc290419Sopenharmony_ci        return;
183cc290419Sopenharmony_ci    };
184cc290419Sopenharmony_ci    let task = arc_task.lock().await;
185cc290419Sopenharmony_ci    hdc::info!("send HdcCommand::AppCheck");
186cc290419Sopenharmony_ci    let file_check_message = TaskMessage {
187cc290419Sopenharmony_ci        channel_id,
188cc290419Sopenharmony_ci        command: HdcCommand::AppCheck,
189cc290419Sopenharmony_ci        payload: task.transfer.transfer_config.serialize(),
190cc290419Sopenharmony_ci    };
191cc290419Sopenharmony_ci    transfer::put(session_id, file_check_message).await
192cc290419Sopenharmony_ci}
193cc290419Sopenharmony_ci
194cc290419Sopenharmony_ciasync fn install_single(session_id: u32, channel_id: u32) -> Result<(), String> {
195cc290419Sopenharmony_ci    let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else {
196cc290419Sopenharmony_ci        hdc::error!("Get host app task failed");
197cc290419Sopenharmony_ci        return Err("Internal error, Pls try again".to_owned());
198cc290419Sopenharmony_ci    };
199cc290419Sopenharmony_ci    let mut task = arc_task.lock().await;
200cc290419Sopenharmony_ci    match task.transfer.task_queue.pop() {
201cc290419Sopenharmony_ci        Some(loc_path) => {
202cc290419Sopenharmony_ci            let loc_pathbuff = PathBuf::from(loc_path.clone());
203cc290419Sopenharmony_ci            if loc_pathbuff.is_file() {
204cc290419Sopenharmony_ci                task.transfer.local_path = loc_path;
205cc290419Sopenharmony_ci                task.transfer.local_tar_raw_path = String::new();
206cc290419Sopenharmony_ci            } else if loc_pathbuff.is_dir() {
207cc290419Sopenharmony_ci                match dir_to_tar(loc_pathbuff) {
208cc290419Sopenharmony_ci                    Ok(tar_file) => {
209cc290419Sopenharmony_ci                        hdc::info!("dir_to_tar success, path = {}", tar_file);
210cc290419Sopenharmony_ci                        task.transfer.local_path = tar_file;
211cc290419Sopenharmony_ci                        task.transfer.local_tar_raw_path = loc_path;
212cc290419Sopenharmony_ci                    }
213cc290419Sopenharmony_ci                    Err(err) => {
214cc290419Sopenharmony_ci                        hdc::error!("{}", err);
215cc290419Sopenharmony_ci                        return Err("Folder packaging failed".to_owned());
216cc290419Sopenharmony_ci                    }
217cc290419Sopenharmony_ci                }
218cc290419Sopenharmony_ci            } else {
219cc290419Sopenharmony_ci                return Err(format!("Error opening file: no such file or directory, path:{loc_path}"));
220cc290419Sopenharmony_ci            }
221cc290419Sopenharmony_ci        }
222cc290419Sopenharmony_ci        None => {
223cc290419Sopenharmony_ci            hdc::info!("task_queue is empty, not need install");
224cc290419Sopenharmony_ci            return Err("Not any installation package was found".to_owned());
225cc290419Sopenharmony_ci        }
226cc290419Sopenharmony_ci    }
227cc290419Sopenharmony_ci    let local_path = task.transfer.local_path.clone();
228cc290419Sopenharmony_ci    let mut file_manager = FileManager::new(local_path.clone());
229cc290419Sopenharmony_ci    let (open_result, error_msg) = file_manager.open();
230cc290419Sopenharmony_ci    if open_result {
231cc290419Sopenharmony_ci        let file_size = file_manager.file_size();
232cc290419Sopenharmony_ci        task.transfer.transfer_config.file_size = file_size;
233cc290419Sopenharmony_ci        task.transfer.file_size = file_size;
234cc290419Sopenharmony_ci        task.transfer.transfer_config.optional_name = utils::get_pseudo_random_u32().to_string();
235cc290419Sopenharmony_ci        if let Some(index) = local_path.rfind('.') {
236cc290419Sopenharmony_ci            let str = local_path.as_str();
237cc290419Sopenharmony_ci            task.transfer
238cc290419Sopenharmony_ci                .transfer_config
239cc290419Sopenharmony_ci                .optional_name
240cc290419Sopenharmony_ci                .push_str(&str[index..]);
241cc290419Sopenharmony_ci        }
242cc290419Sopenharmony_ci        task.transfer.transfer_config.path = task.transfer.remote_path.clone();
243cc290419Sopenharmony_ci        Ok(())
244cc290419Sopenharmony_ci    } else {
245cc290419Sopenharmony_ci        hdc::error!("file_manager.open {error_msg}");
246cc290419Sopenharmony_ci        Err(error_msg)
247cc290419Sopenharmony_ci    }
248cc290419Sopenharmony_ci}
249cc290419Sopenharmony_ci
250cc290419Sopenharmony_ciasync fn init_install(session_id: u32, channel_id: u32, command: &String) -> Result<(), String> {
251cc290419Sopenharmony_ci    let (argv, argc) = Base::split_command_to_args(command);
252cc290419Sopenharmony_ci    if argc < 1 {
253cc290419Sopenharmony_ci        hdc::error!("argc {argc}, {command}");
254cc290419Sopenharmony_ci        return Err("Invalid parameter".to_owned());
255cc290419Sopenharmony_ci    }
256cc290419Sopenharmony_ci
257cc290419Sopenharmony_ci    let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else {
258cc290419Sopenharmony_ci        hdc::error!("Get host app task failed");
259cc290419Sopenharmony_ci        return Err("Internal error, Pls try again".to_owned());
260cc290419Sopenharmony_ci    };
261cc290419Sopenharmony_ci    let mut task = arc_task.lock().await;
262cc290419Sopenharmony_ci    let mut i = 1usize;
263cc290419Sopenharmony_ci    let mut options = String::from("");
264cc290419Sopenharmony_ci    while i < argc as usize {
265cc290419Sopenharmony_ci        if argv[i] == "-cwd" {
266cc290419Sopenharmony_ci            if i + 1 < argc as usize {
267cc290419Sopenharmony_ci                task.transfer.transfer_config.client_cwd = argv[i + 1].clone();
268cc290419Sopenharmony_ci                i += 1;
269cc290419Sopenharmony_ci            }
270cc290419Sopenharmony_ci        } else if argv[i].starts_with('-') {
271cc290419Sopenharmony_ci            if !options.is_empty() {
272cc290419Sopenharmony_ci                options.push(' ');
273cc290419Sopenharmony_ci            }
274cc290419Sopenharmony_ci            options.push_str(&argv[i].clone());
275cc290419Sopenharmony_ci        } else {
276cc290419Sopenharmony_ci            let mut path = argv[i].clone() as String;
277cc290419Sopenharmony_ci            path = Base::extract_relative_path(
278cc290419Sopenharmony_ci                &task.transfer.transfer_config.client_cwd,
279cc290419Sopenharmony_ci                path.as_str(),
280cc290419Sopenharmony_ci            );
281cc290419Sopenharmony_ci            if path.ends_with(".hap") || path.ends_with(".hsp") {
282cc290419Sopenharmony_ci                task.transfer.task_queue.push(path);
283cc290419Sopenharmony_ci            } else {
284cc290419Sopenharmony_ci                let pathbuff = PathBuf::from(path.clone());
285cc290419Sopenharmony_ci                if pathbuff.is_dir() {
286cc290419Sopenharmony_ci                    task.transfer.task_queue.push(path);
287cc290419Sopenharmony_ci                }
288cc290419Sopenharmony_ci            }
289cc290419Sopenharmony_ci        }
290cc290419Sopenharmony_ci        i += 1;
291cc290419Sopenharmony_ci    }
292cc290419Sopenharmony_ci
293cc290419Sopenharmony_ci    if task.transfer.task_queue.is_empty() {
294cc290419Sopenharmony_ci        return Err("Not any installation package was found".to_owned());
295cc290419Sopenharmony_ci    }
296cc290419Sopenharmony_ci
297cc290419Sopenharmony_ci    task.transfer.transfer_config.options = options.clone();
298cc290419Sopenharmony_ci    task.transfer.transfer_config.function_name = TRANSFER_FUNC_NAME.to_string();
299cc290419Sopenharmony_ci    task.transfer.is_master = true;
300cc290419Sopenharmony_ci    drop(task);
301cc290419Sopenharmony_ci    install_single(session_id, channel_id).await
302cc290419Sopenharmony_ci}
303cc290419Sopenharmony_ci
304cc290419Sopenharmony_ciasync fn task_app_install(session_id: u32, channel_id: u32, payload: &[u8]) -> Result<(), String> {
305cc290419Sopenharmony_ci    match String::from_utf8(payload.to_vec()) {
306cc290419Sopenharmony_ci        Ok(str) => {
307cc290419Sopenharmony_ci            hdc::info!("cmd : {str}");
308cc290419Sopenharmony_ci            init_install(session_id, channel_id, &str).await?;
309cc290419Sopenharmony_ci            hdcfile::wake_up_slaver(session_id, channel_id).await;
310cc290419Sopenharmony_ci            put_app_check(session_id, channel_id).await
311cc290419Sopenharmony_ci        }
312cc290419Sopenharmony_ci        Err(e) => {
313cc290419Sopenharmony_ci            hdc::error!("error {}", e);
314cc290419Sopenharmony_ci            let err_msg = "Internal error, Pls try again".to_owned();
315cc290419Sopenharmony_ci            return Err(err_msg);
316cc290419Sopenharmony_ci        }
317cc290419Sopenharmony_ci    }
318cc290419Sopenharmony_ci    Ok(())
319cc290419Sopenharmony_ci}
320cc290419Sopenharmony_ci
321cc290419Sopenharmony_ciasync fn task_app_uninstall(session_id: u32, channel_id: u32, payload: &[u8]) -> Result<(), String> {
322cc290419Sopenharmony_ci    match String::from_utf8(payload.to_vec()) {
323cc290419Sopenharmony_ci        Ok(str) => {
324cc290419Sopenharmony_ci            hdc::info!("cmd {str}");
325cc290419Sopenharmony_ci            let (argv, argc) = Base::split_command_to_args(&str);
326cc290419Sopenharmony_ci            if argc < 1 {
327cc290419Sopenharmony_ci                hdc::error!("argc {argc}");
328cc290419Sopenharmony_ci                let err_msg = String::from("Invalid input parameters");
329cc290419Sopenharmony_ci                return Err(err_msg);
330cc290419Sopenharmony_ci            }
331cc290419Sopenharmony_ci            let (_opt, pack): (Vec<&String>, Vec<&String>) = argv.iter().partition(|arg| arg.starts_with('-'));
332cc290419Sopenharmony_ci            if pack.len() <= 1 {
333cc290419Sopenharmony_ci                let err_msg = String::from("Invalid input parameters");
334cc290419Sopenharmony_ci                return Err(err_msg);
335cc290419Sopenharmony_ci            }
336cc290419Sopenharmony_ci            let options = argv[1..].join(" ");
337cc290419Sopenharmony_ci            let payload = options.as_bytes().to_vec();
338cc290419Sopenharmony_ci            do_app_uninstall(session_id, channel_id, payload).await;
339cc290419Sopenharmony_ci        }
340cc290419Sopenharmony_ci        Err(e) => {
341cc290419Sopenharmony_ci            println!("error {}", e);
342cc290419Sopenharmony_ci            let err_msg = "Internal error, Pls try again".to_owned();
343cc290419Sopenharmony_ci            return Err(err_msg);
344cc290419Sopenharmony_ci        }
345cc290419Sopenharmony_ci    }
346cc290419Sopenharmony_ci    Ok(())
347cc290419Sopenharmony_ci}
348cc290419Sopenharmony_ci
349cc290419Sopenharmony_cipub async fn command_dispatch(
350cc290419Sopenharmony_ci    session_id: u32, channel_id: u32, command: HdcCommand, payload: &[u8],
351cc290419Sopenharmony_ci) -> Result<bool, &str> {
352cc290419Sopenharmony_ci    match command {
353cc290419Sopenharmony_ci        HdcCommand::AppInit => {
354cc290419Sopenharmony_ci            if let Err(err_msg) = task_app_install(session_id, channel_id, payload).await {
355cc290419Sopenharmony_ci                let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await;
356cc290419Sopenharmony_ci                transfer::TcpMap::end(channel_id).await;
357cc290419Sopenharmony_ci                task_finish(session_id, channel_id).await;
358cc290419Sopenharmony_ci                return Ok(false);
359cc290419Sopenharmony_ci            }
360cc290419Sopenharmony_ci        }
361cc290419Sopenharmony_ci        HdcCommand::AppBegin => {
362cc290419Sopenharmony_ci            let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else {
363cc290419Sopenharmony_ci                hdc::error!("Get host app task failed");
364cc290419Sopenharmony_ci                let err_msg = "Internal error, Pls try again".to_owned();
365cc290419Sopenharmony_ci                let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await;
366cc290419Sopenharmony_ci                transfer::TcpMap::end(channel_id).await;
367cc290419Sopenharmony_ci                task_finish(session_id, channel_id).await;
368cc290419Sopenharmony_ci                return Ok(false);
369cc290419Sopenharmony_ci            };
370cc290419Sopenharmony_ci            let task = arc_task.lock().await;
371cc290419Sopenharmony_ci            hdc::info!("recv HdcCommand::AppBegin");
372cc290419Sopenharmony_ci            hdctransfer::transfer_begin(&task.transfer, HdcCommand::AppData).await;
373cc290419Sopenharmony_ci        }
374cc290419Sopenharmony_ci        HdcCommand::AppUninstall => {
375cc290419Sopenharmony_ci            if let Err(err_msg) = task_app_uninstall(session_id, channel_id, payload).await {
376cc290419Sopenharmony_ci                let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await;
377cc290419Sopenharmony_ci                transfer::TcpMap::end(channel_id).await;
378cc290419Sopenharmony_ci                task_finish(session_id, channel_id).await;
379cc290419Sopenharmony_ci                return Ok(false);
380cc290419Sopenharmony_ci            }
381cc290419Sopenharmony_ci        },
382cc290419Sopenharmony_ci        HdcCommand::AppFinish => {
383cc290419Sopenharmony_ci            hdc::info!("recv HdcCommand::AppFinish");
384cc290419Sopenharmony_ci            do_app_finish(session_id, channel_id, payload).await;
385cc290419Sopenharmony_ci        }
386cc290419Sopenharmony_ci        _ => {
387cc290419Sopenharmony_ci            println!("other command");
388cc290419Sopenharmony_ci        }
389cc290419Sopenharmony_ci    }
390cc290419Sopenharmony_ci    Ok(true)
391cc290419Sopenharmony_ci}
392