diff --git a/todo_list/session_manager/1348.patch b/todo_list/session_manager/1348.patch new file mode 100644 index 0000000000000000000000000000000000000000..9511a642dc6658796dcf265fa6973e0053918f74 --- /dev/null +++ b/todo_list/session_manager/1348.patch @@ -0,0 +1,2772 @@ +From 0eb9d31e74dce7ce24cf07b2fafd39e9c6e15d70 Mon Sep 17 00:00:00 2001 +From: "liupeng298@huawei.com" +Date: Thu, 18 Jul 2024 14:29:29 +0800 +Subject: [PATCH] session manager for host sdk + +Signed-off-by: liupeng298@huawei.com +--- + hdc_rust/BUILD.gn | 3 +- + hdc_rust/src/common.rs | 3 +- + hdc_rust/src/common/forward.rs | 95 ++++---- + hdc_rust/src/common/hdcfile.rs | 8 + + hdc_rust/src/common/hdctransfer.rs | 20 +- + hdc_rust/src/config.rs | 16 ++ + hdc_rust/src/daemon_lib/daemon_app.rs | 2 + + hdc_rust/src/daemon_lib/daemon_unity.rs | 3 + + hdc_rust/src/daemon_lib/mod.rs | 33 ++- + hdc_rust/src/daemon_lib/task.rs | 17 +- + hdc_rust/src/daemon_lib/task_manager.rs | 3 +- + hdc_rust/src/host/main.rs | 20 +- + hdc_rust/src/{host => host_transfer}/auth.rs | 40 +-- + .../src/{host => host_transfer}/client.rs | 44 ++-- + .../src/{host => host_transfer}/host_app.rs | 114 ++++++--- + hdc_rust/src/host_transfer/host_usb.rs | 3 +- + .../src/{host => host_transfer}/logger.rs | 4 +- + .../mod.rs} | 16 +- + .../src/{host => host_transfer}/parser.rs | 10 +- + .../src/{host => host_transfer}/server.rs | 58 ++--- + hdc_rust/src/{host => host_transfer}/task.rs | 132 +++++----- + hdc_rust/src/host_transfer/task_manager.rs | 64 +++++ + .../src/{host => host_transfer}/translate.rs | 0 + .../{host => host_transfer}/tty_utility.rs | 7 +- + .../src/{host => host_transfer}/unittest.rs | 0 + hdc_rust/src/lib.rs | 2 + + hdc_rust/src/transfer.rs | 4 +- + hdc_rust/src/transfer/base.rs | 65 ----- + hdc_rust/src/transfer/buffer.rs | 230 ++++++------------ + hdc_rust/src/transfer/usb.rs | 224 ----------------- + hdc_rust/src/utils.rs | 2 +- + 31 files changed, 502 insertions(+), 740 deletions(-) + rename hdc_rust/src/{host => host_transfer}/auth.rs (89%) + rename hdc_rust/src/{host => host_transfer}/client.rs (95%) + rename hdc_rust/src/{host => host_transfer}/host_app.rs (81%) + rename hdc_rust/src/{host => host_transfer}/logger.rs (98%) + rename hdc_rust/src/{host_transfer.rs => host_transfer/mod.rs} (71%) + rename hdc_rust/src/{host => host_transfer}/parser.rs (98%) + rename hdc_rust/src/{host => host_transfer}/server.rs (87%) + rename hdc_rust/src/{host => host_transfer}/task.rs (88%) + create mode 100644 hdc_rust/src/host_transfer/task_manager.rs + rename hdc_rust/src/{host => host_transfer}/translate.rs (100%) + rename hdc_rust/src/{host => host_transfer}/tty_utility.rs (94%) + rename hdc_rust/src/{host => host_transfer}/unittest.rs (100%) + delete mode 100644 hdc_rust/src/transfer/usb.rs + +diff --git a/hdc_rust/BUILD.gn b/hdc_rust/BUILD.gn +index 74894203..fd0cf9ed 100644 +--- a/hdc_rust/BUILD.gn ++++ b/hdc_rust/BUILD.gn +@@ -157,6 +157,7 @@ ohos_rust_static_library("hdc_library_host") { + "//third_party/rust/crates/humantime:lib", + "//third_party/rust/crates/libc:lib", + "//third_party/rust/crates/log:lib", ++ "//third_party/rust/crates/lazy-static.rs:lib", + "//third_party/rust/crates/rust-openssl/openssl:lib", + ] + external_deps = [ "ylong_runtime:ylong_runtime_static" ] +@@ -173,9 +174,9 @@ ohos_rust_executable("hdc_rust") { + ":cffi_host", + ":hdc_library_host", + "//third_party/rust/crates/humantime:lib", +- "//third_party/rust/crates/lazy-static.rs:lib", + "//third_party/rust/crates/libc:lib", + "//third_party/rust/crates/log:lib", ++ "//third_party/rust/crates/lazy-static.rs:lib", + "//third_party/rust/crates/rust-openssl/openssl:lib", + ] + +diff --git a/hdc_rust/src/common.rs b/hdc_rust/src/common.rs +index 6926b249..c854060b 100644 +--- a/hdc_rust/src/common.rs ++++ b/hdc_rust/src/common.rs +@@ -25,4 +25,5 @@ pub mod sendmsg; + pub mod taskbase; + #[cfg(not(target_os = "windows"))] + pub mod uds; +-pub mod unittest; +\ No newline at end of file ++pub mod unittest; ++pub mod context; +\ No newline at end of file +diff --git a/hdc_rust/src/common/forward.rs b/hdc_rust/src/common/forward.rs +index 5f5e6f63..9c02dc50 100644 +--- a/hdc_rust/src/common/forward.rs ++++ b/hdc_rust/src/common/forward.rs +@@ -22,10 +22,12 @@ use libc::SOCK_STREAM; + #[cfg(not(target_os = "windows"))] + use libc::{AF_LOCAL, AF_UNIX, FD_CLOEXEC, F_SETFD}; + use std::collections::HashMap; ++use std::fs::{self, OpenOptions}; + #[cfg(not(target_os = "windows"))] +-use std::fs::{self, File, OpenOptions}; ++use std::fs::File; ++use std::io::{Error, ErrorKind, Write, Result}; + #[cfg(not(target_os = "windows"))] +-use std::io::{self, Error, ErrorKind, Read, Write}; ++use std::io::Read; + use ylong_runtime::sync::{Mutex, RwLock}; + + use crate::common::base::Base; +@@ -35,6 +37,8 @@ use crate::common::hdctransfer::{self, HdcTransferBase}; + use crate::common::jdwp::Jdwp; + #[cfg(not(target_os = "windows"))] + use crate::common::uds::{UdsAddr, UdsClient, UdsServer}; ++use crate::common::context::ContextMap; ++use crate::config::ContextType; + use crate::config::HdcCommand; + use crate::config::MessageLevel; + use crate::config::TaskMessage; +@@ -305,6 +309,28 @@ impl ForwardContextMap { + } + } + } ++ ++ pub async fn clear(cid: u32) { ++ crate::info!("ContextForward remove, cid:{}", cid); ++ let map = Self::get_instance(); ++ let mut map = map.lock().await; ++ map.clear(); ++ } ++ ++ pub async fn dump_task() -> String { ++ let arc = Self::get_instance(); ++ let map = arc.lock().await; ++ let mut result = String::new(); ++ for (_id, context_forward) in map.iter() { ++ result.push_str(&format!( ++ "session_id:{},\tchannel_id:{},\tcommand: {}\n", ++ context_forward.session_id, ++ context_forward.channel_id, ++ context_forward.task_command ++ )); ++ } ++ result ++ } + } + + type MapForward_ = Arc>>; +@@ -323,6 +349,7 @@ impl ForwardTaskMap { + let map = Self::get_instance(); + let mut map = map.lock().await; + map.insert((session_id, channel_id), value.clone()); ++ ContextMap::put(session_id, channel_id, ContextType::Forward).await; + } + + pub async fn remove(session_id: u32, channel_id: u32) { +@@ -379,47 +406,6 @@ impl ForwardTaskMap { + free_channel_task(id.0, id.1).await; + } + } +- +- pub async fn dump_task() -> String { +- let arc = Self::get_instance(); +- let map = arc.lock().await; +- let mut result = String::new(); +- for (_id, forward_task) in map.iter() { +- let forward_type = match forward_task.remote_args.len() { +- 0 => "fport".to_string(), +- 2 => "rport".to_string(), +- _ => "unknown".to_string(), +- }; +- let first_args = match forward_task.remote_args.len() { +- 0 => "unknown".to_string(), +- 2 => format!( +- "{}:{}", +- forward_task.local_args[0], forward_task.local_args[1] +- ), +- _ => "unknown".to_string(), +- }; +- let second_args = match forward_task.remote_args.len() { +- 0 => format!( +- "{}:{}", +- forward_task.local_args[0], forward_task.local_args[1] +- ), +- 2 => format!( +- "{}:{}", +- forward_task.remote_args[0], forward_task.remote_args[1] +- ), +- _ => "unknown".to_string(), +- }; +- result.push_str(&format!( +- "session_id:{},\tchannel_id:{},\tcommand:{:#} {:#} {:#}\n", +- forward_task.session_id, +- forward_task.channel_id, +- forward_type, +- first_args, +- second_args +- )); +- } +- result +- } + } + + pub async fn free_channel_task(session_id: u32, channel_id: u32) { +@@ -466,10 +452,11 @@ pub async fn free_channel_task(session_id: u32, channel_id: u32) { + + pub async fn stop_task(session_id: u32) { + ForwardTaskMap::clear(session_id).await; ++ ForwardContextMap::clear(session_id).await; + } + + pub async fn dump_task() -> String { +- ForwardTaskMap::dump_task().await ++ ForwardContextMap::dump_task().await + } + + #[derive(Debug, Default, Clone, PartialEq, Eq)] +@@ -536,7 +523,7 @@ pub fn check_node_info(value: &String, arg: &mut Vec) -> bool { + } + + #[cfg(feature = "host")] +-pub async fn on_forward_success(task_message: TaskMessage, session_id: u32) -> io::Result<()> { ++pub async fn on_forward_success(task_message: TaskMessage, session_id: u32) -> Result<()> { + crate::info!("on_forward_success"); + let channel_id = task_message.channel_id; + let payload = task_message.payload; +@@ -558,7 +545,7 @@ pub async fn on_forward_success(task_message: TaskMessage, session_id: u32) -> i + crate::error!("payload to String failed. {err}"); + } + } +- transfer::TcpMap::end(task_message.channel_id).await; ++ transfer::ChannelTcpMap::end(task_message.channel_id).await; + Ok(()) + } + +@@ -650,7 +637,7 @@ pub async fn detech_forward_type(ctx_point: &mut ContextForward) -> bool { + true + } + +-pub async fn forward_tcp_accept(ctx: &mut ContextForward, port: u32) -> io::Result<()> { ++pub async fn forward_tcp_accept(ctx: &mut ContextForward, port: u32) -> Result<()> { + let saddr = format!("127.0.0.1:{}", port); + let session_tmp = ctx.session_id; + let channel_tmp = ctx.channel_id; +@@ -938,7 +925,7 @@ async fn server_socket_bind_listen(ctx: &mut ContextForward, path: String) -> bo + true + } + +-pub async fn canonicalize(path: String) -> Result { ++pub async fn canonicalize(path: String) -> Result { + match fs::canonicalize(path) { + Ok(abs_path) => match abs_path.to_str() { + Some(path) => Ok(path.to_string()), +@@ -1144,7 +1131,7 @@ pub async fn daemon_connect_pipe(ctx: &mut ContextForward) { + }); + let addr = UdsAddr::parse_abstract(&socket_name[1..]); + if let Ok(addr_obj) = &addr { +- let ret: Result<(), Error> = UdsClient::wrap_connect(ctx.fd, addr_obj); ++ let ret = UdsClient::wrap_connect(ctx.fd, addr_obj); + if ret.is_err() { + hdctransfer::echo_client( + ctx.session_id, +@@ -1410,13 +1397,13 @@ pub async fn slave_connect( + } + + pub async fn read_data_to_forward(ctx: &mut ContextForward) { +- let cid = ctx.id; +- let session = ctx.session_id; +- let channel = ctx.channel_id; + match ctx.forward_type { + ForwardType::Abstract | ForwardType::FileSystem | ForwardType::Reserved => { + #[cfg(not(target_os = "windows"))] + { ++ let cid = ctx.id; ++ let session = ctx.session_id; ++ let channel = ctx.channel_id; + let fd_temp = ctx.fd; + utils::spawn(async move { + deamon_read_socket_msg(session, channel, fd_temp, cid).await +@@ -1431,9 +1418,9 @@ pub async fn read_data_to_forward(ctx: &mut ContextForward) { + } + } + +-pub fn filter_command(_payload: &[u8]) -> io::Result<(String, u32)> { ++pub fn filter_command(_payload: &[u8]) -> Result<(String, u32)> { + let bytes = &_payload[4..]; +- let ct: Result = String::from_utf8(bytes.to_vec()); ++ let ct = String::from_utf8(bytes.to_vec()); + if let Ok(content) = ct { + let mut id_bytes = [0u8; 4]; + id_bytes.copy_from_slice(&_payload[0..4]); +diff --git a/hdc_rust/src/common/hdcfile.rs b/hdc_rust/src/common/hdcfile.rs +index b5d55d4b..be69c460 100644 +--- a/hdc_rust/src/common/hdcfile.rs ++++ b/hdc_rust/src/common/hdcfile.rs +@@ -29,6 +29,7 @@ use ylong_runtime::sync::Mutex; + + use crate::common::filemanager::FileManager; + use crate::common::hdctransfer::*; ++use crate::config::ContextType; + use crate::config::CompressType; + use crate::config::HdcCommand; + use crate::config::MessageLevel; +@@ -38,6 +39,7 @@ use crate::serializer::serialize::Serialization; + + use super::base::Base; + use super::hdctransfer; ++use super::context::ContextMap; + use crate::serializer::native_struct::TransferConfig; + use crate::utils; + #[cfg(not(feature = "host"))] +@@ -76,6 +78,7 @@ impl FileTaskMap { + let map = Self::get_instance(); + let mut map = map.lock().await; + map.insert((session_id, channel_id), Arc::new(Mutex::new(value))); ++ ContextMap::put(session_id, channel_id, ContextType::File).await; + } + + pub async fn exsit(session_id: u32, channel_id: u32) -> bool { +@@ -600,6 +603,11 @@ pub async fn command_dispatch( + return false; + }; + let mut task = task.lock().await; ++ if task.transfer.stop_run { ++ crate::warn!("command_dispatch stop_run is true."); ++ task_finish(session_id, channel_id).await; ++ return false; ++ } + if hdctransfer::transfer_data(&mut task.transfer, _payload) { + drop(task); + put_file_finish(session_id, channel_id).await; +diff --git a/hdc_rust/src/common/hdctransfer.rs b/hdc_rust/src/common/hdctransfer.rs +index 8998ea81..2ed2114d 100644 +--- a/hdc_rust/src/common/hdctransfer.rs ++++ b/hdc_rust/src/common/hdctransfer.rs +@@ -22,7 +22,6 @@ use std::path::PathBuf; + use std::path::Path; + #[cfg(not(target_os = "windows"))] + use std::os::unix::fs::PermissionsExt; +-use std::sync::Arc; + + use crate::common::base::Base; + use crate::common::hdcfile::FileTaskMap; +@@ -37,7 +36,6 @@ use crate::transfer; + use crate::utils::hdc_log::*; + #[cfg(feature = "host")] + extern crate ylong_runtime_static as ylong_runtime; +-use ylong_runtime::sync::Mutex; + use ylong_runtime::task::JoinHandle; + + extern "C" { +@@ -277,14 +275,14 @@ fn spawn_handler( + _channel_id_: u32, + transfer_config: &TransferConfig, + ) -> JoinHandle<(bool, TaskMessage)> { +- let thread_path_ref = Arc::new(Mutex::new(local_path)); ++ let thread_path_ref = local_path.clone(); + let pos = (index as u64) * (FILE_PACKAGE_PAYLOAD_SIZE as u64); + let compress_type = transfer_config.compress_type; + let file_size = transfer_config.file_size as u64; + ylong_runtime::spawn(async move { +- let path = thread_path_ref.lock().await; ++ let path = thread_path_ref; + let Ok(mut file) = File::open(&*path) else { +- crate::debug!("open file failed, path:{}", *path); ++ crate::debug!("open file failed, path:{}", path); + let _data_message = TaskMessage { + channel_id: _channel_id_, + command: _command_data, +@@ -303,7 +301,7 @@ fn spawn_handler( + } + while read_len < package_read_len { + let Ok(single_len) = file.read(&mut buf[read_len..]) else { +- crate::debug!("file read failed, path:{}", *path); ++ crate::debug!("file read failed, path:{}", path); + break; + }; + read_len += single_len; +@@ -413,6 +411,7 @@ pub async fn read_and_send_data( + _file_size: u64, + _command_data: HdcCommand, + transfer_config: &TransferConfig, ++ transfer: &HdcTransferBase, + ) -> bool { + const MAX_WORKER_COUNT: usize = 5; + let mut pieces_count = (_file_size / FILE_PACKAGE_PAYLOAD_SIZE as u64) as usize; +@@ -442,6 +441,12 @@ pub async fn read_and_send_data( + crate::debug!("read_and_send_data queue is empty"); + break; + } ++ ++ if transfer.stop_run { ++ crate::warn!("read_and_send_data stop_run is true."); ++ break; ++ } ++ + let Some(handler) = queue.pop_front() else { + continue; + }; +@@ -603,6 +608,7 @@ pub async fn transfer_begin(transfer: &HdcTransferBase, _command_data: HdcComman + transfer.file_size, + _command_data, + &transfer.transfer_config, ++ transfer, + ) + .await; + } +@@ -630,7 +636,7 @@ pub async fn transfer_file_finish(channel_id: u32, _session_id: u32, comamnd_fin + } + + pub async fn close_channel(channel_id: u32) { +- transfer::TcpMap::end(channel_id).await; ++ transfer::ChannelTcpMap::end(channel_id).await; + } + + pub async fn echo_client(_session_id: u32, channel_id: u32, message: &str, level: MessageLevel) { +diff --git a/hdc_rust/src/config.rs b/hdc_rust/src/config.rs +index 4f9c0d35..fdd72b00 100644 +--- a/hdc_rust/src/config.rs ++++ b/hdc_rust/src/config.rs +@@ -156,6 +156,7 @@ pub enum HdcCommand { + FlashdProgress, + + UartFinish, ++ DumpTask, + } + + impl TryFrom for HdcCommand { +@@ -233,6 +234,8 @@ impl TryFrom for HdcCommand { + 4007 => Ok(Self::FlashdFormat), + 4008 => Ok(Self::FlashdProgress), + ++ 4010 => Ok(Self::DumpTask), ++ + _ => Err(()), + } + } +@@ -271,6 +274,19 @@ pub enum MessageLevel { + Ok, + } + ++#[allow(unused)] ++#[derive(Clone, Default, Debug)] ++pub enum ContextType { ++ Any, ++ #[default] ++ App, ++ File, ++ Shell, ++ Forward, ++ ExecuteShell, ++ JdwpTrack, ++} ++ + pub const PACKET_FLAG: &[u8] = "HW".as_bytes(); + pub const VER_PROTOCOL: u16 = 1; + pub const ENABLE_IO_CHECK: bool = false; +diff --git a/hdc_rust/src/daemon_lib/daemon_app.rs b/hdc_rust/src/daemon_lib/daemon_app.rs +index 6bb832a7..fe6c0bc9 100644 +--- a/hdc_rust/src/daemon_lib/daemon_app.rs ++++ b/hdc_rust/src/daemon_lib/daemon_app.rs +@@ -18,6 +18,7 @@ + use crate::utils::hdc_log::*; + use crate::common::filemanager::FileManager; + use crate::common::hdctransfer::{self, HdcTransferBase}; ++use crate::common::context::ContextMap; + use crate::config; + use crate::config::HdcCommand; + use crate::config::TaskMessage; +@@ -65,6 +66,7 @@ impl AppTaskMap { + let map = Self::get_instance(); + let mut map = map.lock().await; + map.insert((session_id, channel_id), Arc::new(Mutex::new(value))); ++ ContextMap::put(session_id, channel_id, config::ContextType::App).await; + } + + pub async fn exsit(session_id: u32, channel_id: u32) -> bool { +diff --git a/hdc_rust/src/daemon_lib/daemon_unity.rs b/hdc_rust/src/daemon_lib/daemon_unity.rs +index 1268f998..d4f87e0f 100644 +--- a/hdc_rust/src/daemon_lib/daemon_unity.rs ++++ b/hdc_rust/src/daemon_lib/daemon_unity.rs +@@ -19,6 +19,8 @@ use crate::common::jdwp::Jdwp; + use crate::daemon_lib::sys_para::*; + use crate::utils::hdc_log::*; + use crate::common::hdctransfer; ++use crate::common::context::ContextMap; ++use crate::config::ContextType; + use crate::config::{self, HdcCommand, MessageLevel}; + use libc::sync; + +@@ -234,6 +236,7 @@ async fn do_jdwp_track(session_id: u32, channel_id: u32, payload: &[u8]) { + let jdwp = Jdwp::get_instance().clone(); + jdwp.add_tracker(channel_id, session_id, display) + .await; ++ ContextMap::put(session_id, channel_id, ContextType::JdwpTrack).await; + } + + pub async fn command_dispatch( +diff --git a/hdc_rust/src/daemon_lib/mod.rs b/hdc_rust/src/daemon_lib/mod.rs +index 79ff9287..9ff0fa9d 100644 +--- a/hdc_rust/src/daemon_lib/mod.rs ++++ b/hdc_rust/src/daemon_lib/mod.rs +@@ -23,15 +23,10 @@ pub mod shell; + pub mod task; + pub mod task_manager; + pub mod sys_para; +- + #[cfg(feature = "emulator")] + pub mod bridge; + +-use std::io::{self, ErrorKind}; +-use std::sync::Arc; +-use std::ffi::c_int; + use crate::utils::{self, hdc_log::*}; +- + use crate::common::jdwp::Jdwp; + use crate::config; + use crate::config::TaskMessage; +@@ -45,9 +40,13 @@ use crate::transfer::uart::UartReader; + #[cfg(not(feature = "emulator"))] + use crate::transfer::uart_wrapper; + use crate::transfer::buffer::DiedSession; +- ++use crate::daemon_transfer::usb; + use crate::daemon_lib::sys_para::*; ++ + use std::ffi::CString; ++use std::io::{self, ErrorKind}; ++use std::sync::Arc; ++use std::ffi::c_int; + #[cfg(not(feature = "emulator"))] + use ylong_runtime::net::{TcpListener, TcpStream}; + #[cfg(not(feature = "emulator"))] +@@ -56,6 +55,11 @@ use ylong_runtime::sync::mpsc; + use libc::c_void; + type XCollieCallbackRust = extern "C" fn(arg: *mut libc::c_void); + ++/// # Safety ++pub unsafe extern "C" fn new_session_callback(_ptr: *mut c_void) { ++ crate::error!("new session proc timeout, will restart hdcd"); ++} ++ + extern "C" { + #[cfg(not(feature = "emulator"))] + fn NeedDropRootPrivileges() -> c_int; +@@ -359,11 +363,11 @@ pub async fn uart_handle_client(fd: i32) -> io::Result<()> { + #[cfg(not(feature = "emulator"))] + pub async fn usb_daemon_start() -> io::Result<()> { + loop { +- let ret = transfer::usb::usb_init(); ++ let ret = usb::usb_init(); + match ret { + Ok((config_fd, bulkin_fd, bulkout_fd)) => { + let _ = usb_handle_client(config_fd, bulkin_fd, bulkout_fd).await; +- transfer::usb::usb_close(config_fd, bulkin_fd, bulkout_fd); ++ usb::usb_close(config_fd, bulkin_fd, bulkout_fd); + } + Err(e) => { + crate::error!("usb init failure and restart hdcd error is {:?}", e); +@@ -373,15 +377,10 @@ pub async fn usb_daemon_start() -> io::Result<()> { + } + } + +-/// # Safety +-pub unsafe extern "C" fn new_session_callback(_ptr: *mut c_void) { +- crate::error!("new session proc timeout, will restart hdcd"); +-} +- + #[cfg(not(feature = "emulator"))] + pub async fn usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) -> io::Result<()> { +- let _rd = transfer::usb::UsbReader { fd: bulkin_fd }; +- let mut rx = transfer::usb_start_recv(bulkin_fd, 0); ++ let _rd = usb::UsbReader { fd: bulkin_fd }; ++ let mut rx = usb::usb_start_recv(bulkin_fd, 0); + let mut cur_session_id = 0; + loop { + match rx.recv().await { +@@ -395,8 +394,8 @@ pub async fn usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) + let timer = unsafe { hicollie_rust::set_timer("new session".as_ptr(), 10 /* second */, new_session_func, std::ptr::null_mut() as *mut c_void, 3) }; + task_manager::free_session(cur_session_id).await; + crate::info!("free session(usb) over {:?} and new session is {}", cur_session_id, session_id_in_msg); +- let wr = transfer::usb::UsbWriter { fd: bulkout_fd }; +- transfer::UsbMap::start(session_id_in_msg, wr).await; ++ let wr = usb::UsbWriter { fd: bulkout_fd }; ++ usb::UsbMap::start(session_id_in_msg, wr).await; + cur_session_id = session_id_in_msg; + hicollie_rust::cancel_timer(timer); + } +diff --git a/hdc_rust/src/daemon_lib/task.rs b/hdc_rust/src/daemon_lib/task.rs +index f68133bc..656d9bb5 100644 +--- a/hdc_rust/src/daemon_lib/task.rs ++++ b/hdc_rust/src/daemon_lib/task.rs +@@ -24,7 +24,7 @@ use crate::daemon_lib::sys_para::*; + use crate::utils::hdc_log::*; + use crate::common::forward::{self, ForwardTaskMap, HdcForward}; + use crate::common::hdcfile::{self, FileTaskMap, HdcFile}; +-use crate::common::jdwp; ++use crate::common::context::ContextMap; + use crate::config::*; + use crate::transfer; + +@@ -87,19 +87,6 @@ async fn daemon_shell_task(task_message: TaskMessage, session_id: u32) -> io::Re + Ok(()) + } + +-async fn remove_task(session_id: u32, channel_id: u32) { +- jdwp::stop_task(session_id, channel_id).await; +- AppTaskMap::remove(session_id, channel_id).await; +- FileTaskMap::remove(session_id, channel_id).await; +- forward::free_channel_task(session_id, channel_id).await; +- // shell & hilog task +- if let Some(pty_task) = PtyMap::get(session_id, channel_id).await { +- let _ = &pty_task.tx.send(vec![0x04_u8]).await; +- PtyMap::del(session_id, channel_id).await; +- } +- ShellExecuteMap::del(session_id, channel_id).await; +-} +- + async fn daemon_channel_close(task_message: TaskMessage, session_id: u32) -> io::Result<()> { + // task stop: + crate::debug!( +@@ -107,7 +94,7 @@ async fn daemon_channel_close(task_message: TaskMessage, session_id: u32) -> io: + task_message.channel_id + ); + +- remove_task(session_id, task_message.channel_id).await; ++ ContextMap::channel_close(session_id, task_message.channel_id).await; + + if task_message.payload[0] > 0 { + let message = TaskMessage { +diff --git a/hdc_rust/src/daemon_lib/task_manager.rs b/hdc_rust/src/daemon_lib/task_manager.rs +index 5b7f0a90..1e1bbfb6 100644 +--- a/hdc_rust/src/daemon_lib/task_manager.rs ++++ b/hdc_rust/src/daemon_lib/task_manager.rs +@@ -13,7 +13,6 @@ + * limitations under the License. + */ + //! shell +- + #[allow(unused_imports)] + use crate::daemon_lib::daemon_app; + use crate::daemon_lib::shell; +@@ -29,7 +28,7 @@ use crate::utils::hdc_log::*; + use crate::config::ConnectType; + use crate::transfer::buffer; + use crate::transfer::TcpMap; +-use crate::transfer::UsbMap; ++use crate::daemon_transfer::usb::UsbMap; + use crate::transfer::ConnectTypeMap; + + pub async fn free_all_sessiones() { +diff --git a/hdc_rust/src/host/main.rs b/hdc_rust/src/host/main.rs +index de773267..a646945e 100644 +--- a/hdc_rust/src/host/main.rs ++++ b/hdc_rust/src/host/main.rs +@@ -13,18 +13,9 @@ + * limitations under the License. + */ + //! host server & client +- +-mod auth; +-mod client; +-mod host_app; +-mod logger; +-mod parser; +-mod server; +-mod task; +-mod translate; +-mod unittest; +-mod tty_utility; +- ++extern crate lazy_static; ++use hdc::host_transfer; ++use hdc::host_transfer::*; + use std::{ + backtrace::{Backtrace, BacktraceStatus}, + io::ErrorKind, +@@ -38,9 +29,6 @@ use hdc::config; + #[cfg(feature = "host")] + extern crate ylong_runtime_static as ylong_runtime; + +-#[macro_use] +-extern crate lazy_static; +- + // static LOGGER: SimpleHostLogger = SimpleHostLogger; + + // fn logger_init(log_level: log::LevelFilter) { +@@ -73,7 +61,7 @@ fn main() { + .keep_alive_time(std::time::Duration::from_secs(10)) + .build_global(); + +- let parsed_cmd = match parser::parse_command(std::env::args()) { ++ let parsed_cmd = match host_transfer::parser::parse_command(std::env::args()) { + Ok(parsed_cmd) => parsed_cmd, + Err(e) => { + println!("{}", e); +diff --git a/hdc_rust/src/host/auth.rs b/hdc_rust/src/host_transfer/auth.rs +similarity index 89% +rename from hdc_rust/src/host/auth.rs +rename to hdc_rust/src/host_transfer/auth.rs +index 7edc16b9..be9de896 100644 +--- a/hdc_rust/src/host/auth.rs ++++ b/hdc_rust/src/host_transfer/auth.rs +@@ -17,11 +17,11 @@ + + use crate::config::*; + +-use hdc::config; +-use hdc::config::TaskMessage; +-use hdc::serializer::native_struct::SessionHandShake; +-use hdc::serializer::serialize::Serialization; +-use hdc::transfer; ++use crate::config; ++use crate::config::TaskMessage; ++use crate::serializer::native_struct::SessionHandShake; ++use crate::serializer::serialize::Serialization; ++use crate::transfer; + + use std::io::{self, Error, ErrorKind}; + use std::path::Path; +@@ -30,8 +30,10 @@ use openssl::base64; + use openssl::rsa::{Padding, Rsa}; + #[cfg(feature = "host")] + extern crate ylong_runtime_static as ylong_runtime; +-use crate::task::{ConnectMap, ConnectStatus, DaemonInfo}; +-use hdc::common::base::Base; ++use super::task::{ConnectMap, ConnectStatus, DaemonInfo}; ++use crate::common::base::Base; ++#[allow(unused)] ++use crate::utils::hdc_log::*; + + pub async fn start_handshake_with_daemon( + connect_key: String, session_id: u32, channel_id: u32, conn_type: ConnectType, +@@ -92,7 +94,7 @@ async fn handshake_deal_daemon_auth_result(daemon: SessionHandShake, connect_key + }; + } + +- hdc::info!( ++ crate::info!( + "daemon auth result[{}] key[{}] ver[{}] devname[{}] emgmsg[{}]", + auth_result.clone(), + connect_key.clone(), +@@ -113,7 +115,7 @@ async fn handshake_deal_daemon_auth_result(daemon: SessionHandShake, connect_key + { + Ok(()) + } else { +- hdc::error!("update connect status for {} failed", connect_key); ++ crate::error!("update connect status for {} failed", connect_key); + Err(Error::new(ErrorKind::Other, "not exist connect key")) + } + } +@@ -123,10 +125,10 @@ pub async fn handshake_task(msg: TaskMessage, session_id: u32, connect_key: Stri + let mut recv = SessionHandShake::default(); + let channel_id = msg.channel_id; + recv.parse(msg.payload)?; +- hdc::info!("recv handshake: {:#?}", recv); ++ crate::info!("recv handshake: {:#?}", recv); + + if recv.banner != config::HANDSHAKE_MESSAGE { +- hdc::info!("invalid banner {}", recv.banner); ++ crate::info!("invalid banner {}", recv.banner); + return Err(Error::new(ErrorKind::Other, "Recv server-hello failed")); + } + +@@ -162,10 +164,10 @@ pub async fn handshake_task(msg: TaskMessage, session_id: u32, connect_key: Stri + send_handshake_to_daemon(&handshake, channel_id).await; + return Ok(()); + } else if recv.auth_type == config::AuthType::Fail as u8 { +- hdc::info!("daemon auth failed"); ++ crate::info!("daemon auth failed"); + return Err(Error::new(ErrorKind::Other, recv.buf.as_str())); + } else { +- hdc::info!("invalid auth type {}", recv.auth_type); ++ crate::info!("invalid auth type {}", recv.auth_type); + return Err(Error::new(ErrorKind::Other, "unknown auth type")); + } + } +@@ -175,14 +177,14 @@ fn load_or_create_prikey() -> io::Result> { + + if let Ok(pem) = std::fs::read(&file) { + if let Ok(prikey) = Rsa::private_key_from_pem(&pem) { +- hdc::info!("found existed private key"); ++ crate::info!("found existed private key"); + return Ok(prikey); + } else { +- hdc::error!("found broken private key, regenerating..."); ++ crate::error!("found broken private key, regenerating..."); + } + } + +- hdc::info!("create private key at {:#?}", file); ++ crate::info!("create private key at {:#?}", file); + create_prikey() + } + +@@ -195,7 +197,7 @@ pub fn create_prikey() -> io::Result> { + let _ = std::fs::create_dir_all(&path); + + if std::fs::write(file, pem).is_err() { +- hdc::error!("write private key failed"); ++ crate::error!("write private key failed"); + Err(Error::new(ErrorKind::Other, "write private key failed")) + } else { + Ok(prikey) +@@ -223,7 +225,7 @@ fn get_signature_b64(rsa: &Rsa, plain: String) -> io::Re + } + + async fn send_handshake_to_daemon(handshake: &SessionHandShake, channel_id: u32) { +- hdc::info!("send handshake: {:#?}", handshake.clone()); ++ crate::info!("send handshake: {:#?}", handshake.clone()); + transfer::put( + handshake.session_id, + TaskMessage { channel_id, command: config::HdcCommand::KernelHandshake, payload: handshake.serialize() }, +@@ -243,7 +245,7 @@ fn get_home_dir() -> String { + if let Ok(result) = output { + String::from_utf8(result.stdout).unwrap().trim().to_string() + } else { +- hdc::warn!("get home dir failed, use current dir instead"); ++ crate::warn!("get home dir failed, use current dir instead"); + ".".to_string() + } + } +diff --git a/hdc_rust/src/host/client.rs b/hdc_rust/src/host_transfer/client.rs +similarity index 95% +rename from hdc_rust/src/host/client.rs +rename to hdc_rust/src/host_transfer/client.rs +index eac1a135..069e2986 100644 +--- a/hdc_rust/src/host/client.rs ++++ b/hdc_rust/src/host_transfer/client.rs +@@ -15,13 +15,13 @@ + use super::parser::ParsedCommand; + use super::server; + +-use hdc::common::base; +-use hdc::common::base::Base; +-use hdc::config::{self, HdcCommand}; +-use hdc::transfer; +-use hdc::utils; ++use crate::common::base; ++use crate::common::base::Base; ++use crate::config::{self, HdcCommand}; ++use crate::transfer; ++use crate::utils; + #[allow(unused)] +-use hdc::utils::hdc_log::*; ++use crate::utils::hdc_log::*; + use libc::exit; + use std::time::Duration; + +@@ -30,7 +30,7 @@ use std::io::{self, Error, ErrorKind, Write}; + #[cfg(not(target_os = "windows"))] + use std::os::fd::AsRawFd; + +-#[cfg(featrue = "host")] ++#[cfg(feature = "host")] + extern crate ylong_runtime_static as ylong_runtime; + #[cfg(not(target_os = "windows"))] + use ylong_runtime::io::AsyncReadExt; +@@ -38,7 +38,7 @@ use ylong_runtime::io::AsyncWriteExt; + use ylong_runtime::net::{SplitWriteHalf, TcpStream}; + + #[cfg(target_os = "windows")] +-use crate::tty_utility::*; ++use super::tty_utility::*; + + #[cfg(target_os = "windows")] + extern "C" { +@@ -82,7 +82,7 @@ pub async fn run_client_mode(parsed_cmd: ParsedCommand) -> io::Result<()> { + let mut client = Client::new(parsed_cmd).await?; + + if let Err(e) = client.handshake().await { +- hdc::error!("handshake with server failed: {e:?}"); ++ crate::error!("handshake with server failed: {e:?}"); + return Err(e); + } + client.execute_command().await +@@ -114,11 +114,12 @@ impl Client { + + async fn execute_command(&mut self) -> io::Result<()> { + let entire_cmd = self.params.join(" "); +- hdc::debug!("execute command params: {}", &entire_cmd); ++ crate::debug!("execute command params: {}", &entire_cmd); + + match self.command { + HdcCommand::KernelTargetList + | HdcCommand::KernelTargetConnect ++ | HdcCommand::DumpTask + | HdcCommand::UnityHilog => self.general_task().await, + HdcCommand::FileInit | HdcCommand::FileCheck | HdcCommand::FileRecvInit => { + self.file_send_task().await +@@ -174,13 +175,13 @@ impl Client { + } + + async fn send(&mut self, buf: &[u8]) { +- hdc::debug!("channel send buf: {:#?}", buf); ++ crate::debug!("channel send buf: {:#?}", buf); + let msg = [u32::to_be_bytes(buf.len() as u32).as_slice(), buf].concat(); + let _ = self.wr.write_all(msg.as_slice()).await; + } + + async fn recv(&mut self) -> io::Result> { +- hdc::debug!("channel recv buf"); ++ crate::debug!("channel recv buf"); + transfer::ChannelMap::recv().await + } + +@@ -246,7 +247,7 @@ impl Client { + } + + let unicode_byte = unicode_assemble(c); +- hdc::info!("unicode_byte is {:?}", unicode_byte); ++ crate::info!("unicode_byte is {:?}", unicode_byte); + self.send(unicode_byte.as_slice()).await; + } + Ok(()) +@@ -320,7 +321,7 @@ impl Client { + self.send(self.params.join(" ").as_bytes()).await; + loop { + let recv = self.recv().await?; +- hdc::debug!( ++ crate::debug!( + "general_task recv: {:#?}", + recv.iter() + .map(|c| format!("{c:02x}")) +@@ -363,7 +364,7 @@ impl Client { + let recv = self.recv().await; + match recv { + Ok(recv) => { +- hdc::debug!( ++ crate::debug!( + "recv: {:#?}", + recv.iter() + .map(|c| format!("{c:02x}")) +@@ -387,7 +388,7 @@ impl Client { + let recv = self.recv().await; + match recv { + Ok(recv) => { +- hdc::debug!( ++ crate::debug!( + "recv: {:#?}", + recv.iter() + .map(|c| format!("{c:02x}")) +@@ -398,11 +399,11 @@ impl Client { + let wait_for = "No connected target\r\n".to_string(); + if wait_for == String::from_utf8(recv).expect("invalid UTF-8") { + self.send(self.params.join(" ").as_bytes()).await; +- hdc::debug!("WaitFor sleep a second"); ++ crate::debug!("WaitFor sleep a second"); + let wait_interval = 1000; + ylong_runtime::time::sleep(Duration::from_millis(wait_interval)).await; + } else { +- hdc::debug!("exit client"); ++ crate::debug!("exit client"); + unsafe { + exit(0); + } +@@ -431,7 +432,7 @@ impl Client { + let recv = self.recv().await; + match recv { + Ok(recv) => { +- hdc::debug!( ++ crate::debug!( + "app_install_task recv: {:#?}", + recv.iter() + .map(|c| format!("{c:02x}")) +@@ -458,7 +459,7 @@ impl Client { + let recv = self.recv().await; + match recv { + Ok(recv) => { +- hdc::debug!( ++ crate::debug!( + "app_uninstall_task recv: {:#?}", + recv.iter() + .map(|c| format!("{c:02x}")) +@@ -486,7 +487,7 @@ impl Client { + let recv = self.recv().await; + match recv { + Ok(recv) => { +- hdc::debug!( ++ crate::debug!( + "check_server_task recv: {:#?}", + recv.iter() + .map(|c| format!("{c:02x}")) +@@ -529,6 +530,7 @@ fn auto_connect_key(key: String, cmd: HdcCommand) -> String { + | HdcCommand::KernelCheckServer + | HdcCommand::KernelTargetConnect + | HdcCommand::KernelCheckDevice ++ | HdcCommand::DumpTask + | HdcCommand::KernelServerKill => "".to_string(), + _ => { + if key.is_empty() { +diff --git a/hdc_rust/src/host/host_app.rs b/hdc_rust/src/host_transfer/host_app.rs +similarity index 81% +rename from hdc_rust/src/host/host_app.rs +rename to hdc_rust/src/host_transfer/host_app.rs +index da25181f..383263a8 100644 +--- a/hdc_rust/src/host/host_app.rs ++++ b/hdc_rust/src/host_transfer/host_app.rs +@@ -12,25 +12,28 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +-use hdc::common::base::Base; +-use hdc::common::filemanager::FileManager; +-use hdc::common::hdcfile; +-use hdc::common::hdctransfer::{self, HdcTransferBase}; +-use hdc::config::HdcCommand; +-use hdc::config::TaskMessage; +-use hdc::config::TRANSFER_FUNC_NAME; +-use hdc::config::{self, INSTALL_TAR_MAX_CNT}; +-use hdc::serializer::serialize::Serialization; +-use hdc::transfer; +-use hdc::transfer::EchoLevel; +-use hdc::utils; ++use crate::common::base::Base; ++use crate::common::filemanager::FileManager; ++use crate::common::hdcfile; ++use crate::common::hdctransfer::{self, HdcTransferBase}; ++use crate::common::context::ContextMap; ++use crate::config::HdcCommand; ++use crate::config::TaskMessage; ++use crate::config::TRANSFER_FUNC_NAME; ++use crate::config::{self, INSTALL_TAR_MAX_CNT}; ++use crate::serializer::serialize::Serialization; ++use crate::transfer; ++use crate::transfer::EchoLevel; ++use crate::utils; ++#[allow(unused)] ++use crate::utils::hdc_log::*; + use std::collections::HashMap; + use std::path::PathBuf; + use std::sync::Arc; + use ylong_runtime::sync::Mutex; + #[cfg(feature = "host")] + extern crate ylong_runtime_static as ylong_runtime; +-use hdc::tar::compress::Compress; ++use crate::tar::compress::Compress; + + pub struct HostAppTask { + pub transfer: HdcTransferBase, +@@ -68,6 +71,7 @@ impl HostAppTaskMap { + (session_id, channel_id), + Arc::new(Mutex::new(host_app_task)), + ); ++ ContextMap::put(session_id, channel_id, config::ContextType::App).await; + } + + pub async fn exist(session_id: u32, channel_id: u32) -> Result { +@@ -90,6 +94,35 @@ impl HostAppTaskMap { + }; + Some(arc_task.clone()) + } ++ ++ async fn stop_task(session_id: u32) { ++ let arc = Self::get_instance(); ++ let map = arc.lock().await; ++ crate::info!("app stop_task, session_id:{}, task_size: {}", session_id, map.len()); ++ for _iter in map.iter() { ++ if _iter.0 .0 != session_id { ++ continue; ++ } ++ let mut task = _iter.1.lock().await; ++ task.transfer.stop_run = true; ++ } ++ } ++ ++ async fn dump_task() -> String { ++ let arc = Self::get_instance(); ++ let map = arc.lock().await; ++ let mut result = String::new(); ++ for _iter in map.iter() { ++ let task = _iter.1.lock().await; ++ let command = task.transfer.command_str.clone(); ++ let line = format!( ++ "session_id:{},\tchannel_id:{},\tcommand:{}", ++ _iter.0 .0, _iter.0 .1, command ++ ); ++ result.push_str(line.as_str()); ++ } ++ result ++ } + } + + async fn check_install_continue( +@@ -103,7 +136,7 @@ async fn check_install_continue( + config::AppModeType::UnInstall => String::from("App uninstall"), + }; + let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else { +- hdc::error!("Get host app task failed"); ++ crate::error!("Get host app task failed"); + return false; + }; + let mut task = arc_task.lock().await; +@@ -115,7 +148,7 @@ async fn check_install_continue( + }; + let message = + format!("{} path:{}, queuesize:{}, msg:{}", mode_desc, local_path, task.transfer.task_queue.len(), msg); +- hdc::info!("{message}"); ++ crate::info!("{message}"); + task.printed_msg_len = str.len(); + let _ = transfer::send_channel_msg(channel_id, EchoLevel::INFO, message).await; + if task.transfer.task_queue.is_empty() { +@@ -135,7 +168,7 @@ async fn check_install_continue( + } + + async fn do_app_uninstall(session_id: u32, channel_id: u32, payload: Vec) { +- hdc::info!("send HdcCommand::AppUninstall"); ++ crate::info!("send HdcCommand::AppUninstall"); + let app_uninstall_message = TaskMessage { channel_id, command: HdcCommand::AppUninstall, payload }; + transfer::put(session_id, app_uninstall_message).await; + } +@@ -146,7 +179,7 @@ async fn do_app_finish(session_id: u32, channel_id: u32, payload: &[u8]) -> bool + let str = match String::from_utf8(payload[2..].to_vec()) { + Ok(str) => str, + Err(err) => { +- hdc::error!("do_app_finish from_utf8 error, {err}"); ++ crate::error!("do_app_finish from_utf8 error, {err}"); + return false; + } + }; +@@ -178,11 +211,11 @@ async fn task_finish(session_id: u32, channel_id: u32) { + + async fn put_app_check(session_id: u32, channel_id: u32) { + let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else { +- hdc::error!("Get host app task failed"); ++ crate::error!("Get host app task failed"); + return; + }; + let task = arc_task.lock().await; +- hdc::info!("send HdcCommand::AppCheck"); ++ crate::info!("send HdcCommand::AppCheck"); + let file_check_message = TaskMessage { + channel_id, + command: HdcCommand::AppCheck, +@@ -193,7 +226,7 @@ async fn put_app_check(session_id: u32, channel_id: u32) { + + async fn install_single(session_id: u32, channel_id: u32) -> Result<(), String> { + let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else { +- hdc::error!("Get host app task failed"); ++ crate::error!("Get host app task failed"); + return Err("Internal error, Pls try again".to_owned()); + }; + let mut task = arc_task.lock().await; +@@ -206,12 +239,12 @@ async fn install_single(session_id: u32, channel_id: u32) -> Result<(), String> + } else if loc_pathbuff.is_dir() { + match dir_to_tar(loc_pathbuff) { + Ok(tar_file) => { +- hdc::info!("dir_to_tar success, path = {}", tar_file); ++ crate::info!("dir_to_tar success, path = {}", tar_file); + task.transfer.local_path = tar_file; + task.transfer.local_tar_raw_path = loc_path; + } + Err(err) => { +- hdc::error!("{}", err); ++ crate::error!("{}", err); + return Err("Folder packaging failed".to_owned()); + } + } +@@ -220,7 +253,7 @@ async fn install_single(session_id: u32, channel_id: u32) -> Result<(), String> + } + } + None => { +- hdc::info!("task_queue is empty, not need install"); ++ crate::info!("task_queue is empty, not need install"); + return Err("Not any installation package was found".to_owned()); + } + } +@@ -242,7 +275,7 @@ async fn install_single(session_id: u32, channel_id: u32) -> Result<(), String> + task.transfer.transfer_config.path = task.transfer.remote_path.clone(); + Ok(()) + } else { +- hdc::error!("file_manager.open {error_msg}"); ++ crate::error!("file_manager.open {error_msg}"); + Err(error_msg) + } + } +@@ -250,15 +283,16 @@ async fn install_single(session_id: u32, channel_id: u32) -> Result<(), String> + async fn init_install(session_id: u32, channel_id: u32, command: &String) -> Result<(), String> { + let (argv, argc) = Base::split_command_to_args(command); + if argc < 1 { +- hdc::error!("argc {argc}, {command}"); ++ crate::error!("argc {argc}, {command}"); + return Err("Invalid parameter".to_owned()); + } + + let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else { +- hdc::error!("Get host app task failed"); ++ crate::error!("Get host app task failed"); + return Err("Internal error, Pls try again".to_owned()); + }; + let mut task = arc_task.lock().await; ++ task.transfer.command_str = command.clone(); + let mut i = 1usize; + let mut options = String::from(""); + while i < argc as usize { +@@ -304,13 +338,13 @@ async fn init_install(session_id: u32, channel_id: u32, command: &String) -> Res + async fn task_app_install(session_id: u32, channel_id: u32, payload: &[u8]) -> Result<(), String> { + match String::from_utf8(payload.to_vec()) { + Ok(str) => { +- hdc::info!("cmd : {str}"); ++ crate::info!("cmd : {str}"); + init_install(session_id, channel_id, &str).await?; + hdcfile::wake_up_slaver(session_id, channel_id).await; + put_app_check(session_id, channel_id).await + } + Err(e) => { +- hdc::error!("error {}", e); ++ crate::error!("error {}", e); + let err_msg = "Internal error, Pls try again".to_owned(); + return Err(err_msg); + } +@@ -321,10 +355,10 @@ async fn task_app_install(session_id: u32, channel_id: u32, payload: &[u8]) -> R + async fn task_app_uninstall(session_id: u32, channel_id: u32, payload: &[u8]) -> Result<(), String> { + match String::from_utf8(payload.to_vec()) { + Ok(str) => { +- hdc::info!("cmd {str}"); ++ crate::info!("cmd {str}"); + let (argv, argc) = Base::split_command_to_args(&str); + if argc < 1 { +- hdc::error!("argc {argc}"); ++ crate::error!("argc {argc}"); + let err_msg = String::from("Invalid input parameters"); + return Err(err_msg); + } +@@ -353,34 +387,34 @@ pub async fn command_dispatch( + HdcCommand::AppInit => { + if let Err(err_msg) = task_app_install(session_id, channel_id, payload).await { + let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await; +- transfer::TcpMap::end(channel_id).await; ++ transfer::ChannelTcpMap::end(channel_id).await; + task_finish(session_id, channel_id).await; + return Ok(false); + } + } + HdcCommand::AppBegin => { + let Some(arc_task) = HostAppTaskMap::get(session_id, channel_id).await else { +- hdc::error!("Get host app task failed"); ++ crate::error!("Get host app task failed"); + let err_msg = "Internal error, Pls try again".to_owned(); + let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await; +- transfer::TcpMap::end(channel_id).await; ++ transfer::ChannelTcpMap::end(channel_id).await; + task_finish(session_id, channel_id).await; + return Ok(false); + }; + let task = arc_task.lock().await; +- hdc::info!("recv HdcCommand::AppBegin"); ++ crate::info!("recv HdcCommand::AppBegin"); + hdctransfer::transfer_begin(&task.transfer, HdcCommand::AppData).await; + } + HdcCommand::AppUninstall => { + if let Err(err_msg) = task_app_uninstall(session_id, channel_id, payload).await { + let _ = transfer::send_channel_msg(channel_id, EchoLevel::FAIL, err_msg).await; +- transfer::TcpMap::end(channel_id).await; ++ transfer::ChannelTcpMap::end(channel_id).await; + task_finish(session_id, channel_id).await; + return Ok(false); + } + }, + HdcCommand::AppFinish => { +- hdc::info!("recv HdcCommand::AppFinish"); ++ crate::info!("recv HdcCommand::AppFinish"); + do_app_finish(session_id, channel_id, payload).await; + } + _ => { +@@ -389,3 +423,11 @@ pub async fn command_dispatch( + } + Ok(true) + } ++ ++pub async fn stop_task(session_id: u32) { ++ HostAppTaskMap::stop_task(session_id).await; ++} ++ ++pub async fn dump_task() -> String { ++ HostAppTaskMap::dump_task().await ++} +diff --git a/hdc_rust/src/host_transfer/host_usb.rs b/hdc_rust/src/host_transfer/host_usb.rs +index 5ee81a02..5f267a24 100644 +--- a/hdc_rust/src/host_transfer/host_usb.rs ++++ b/hdc_rust/src/host_transfer/host_usb.rs +@@ -26,16 +26,17 @@ use crate::transfer::base; + use crate::utils; + #[allow(unused)] + use crate::utils::hdc_log::*; +- + use crate::config::ConnectType; + use crate::config::TaskMessage; + use crate::transfer::base::Reader; + use crate::transfer::base::Writer; + use crate::transfer::buffer::ConnectTypeMap; ++ + use std::collections::HashMap; + use std::io::{self, Error, ErrorKind}; + use std::string::FromUtf8Error; + use std::sync::Arc; ++ + use ylong_runtime::sync::mpsc; + use ylong_runtime::sync::mpsc::BoundedSender; + use ylong_runtime::sync::Mutex; +diff --git a/hdc_rust/src/host/logger.rs b/hdc_rust/src/host_transfer/logger.rs +similarity index 98% +rename from hdc_rust/src/host/logger.rs +rename to hdc_rust/src/host_transfer/logger.rs +index 12d4aae4..c6c90787 100644 +--- a/hdc_rust/src/host/logger.rs ++++ b/hdc_rust/src/host_transfer/logger.rs +@@ -17,7 +17,7 @@ use std::path::Path; + use std::sync::{Arc, Mutex}; + use std::time::SystemTime; + +-use hdc::config; ++use crate::config; + + // #[derive(Default)] + +@@ -106,7 +106,7 @@ impl HostLoggerMeta { + }; + if file_path.exists() { + if let Err(err) = std::fs::rename(&file_path, file_cache_path) { +- hdc::error!("rename failed, {err}"); ++ crate::error!("rename failed, {err}"); + } + } + } +diff --git a/hdc_rust/src/host_transfer.rs b/hdc_rust/src/host_transfer/mod.rs +similarity index 71% +rename from hdc_rust/src/host_transfer.rs +rename to hdc_rust/src/host_transfer/mod.rs +index d881f59f..addddb4f 100644 +--- a/hdc_rust/src/host_transfer.rs ++++ b/hdc_rust/src/host_transfer/mod.rs +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2024 Huawei Device Co., Ltd. ++ * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at +@@ -12,6 +12,18 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +-//! host_transfer ++//! host + #![allow(missing_docs)] ++ ++pub mod auth; ++pub mod client; ++pub mod host_app; + pub mod host_usb; ++pub mod logger; ++pub mod parser; ++pub mod server; ++pub mod task_manager; ++pub mod task; ++pub mod translate; ++pub mod tty_utility; ++pub mod unittest; +diff --git a/hdc_rust/src/host/parser.rs b/hdc_rust/src/host_transfer/parser.rs +similarity index 98% +rename from hdc_rust/src/host/parser.rs +rename to hdc_rust/src/host_transfer/parser.rs +index 96e7ad5d..00c1bb72 100644 +--- a/hdc_rust/src/host/parser.rs ++++ b/hdc_rust/src/host_transfer/parser.rs +@@ -14,13 +14,14 @@ + */ + use super::translate; + +-use hdc::config::{self, HdcCommand}; ++use crate::config::{self, HdcCommand}; + +-use hdc::utils; +-use std::collections::HashMap; ++use crate::utils; + use std::io::{self, Error, ErrorKind}; + use std::str::FromStr; ++use std::collections::HashMap; + ++use lazy_static::lazy_static; + #[derive(Default, Debug, Clone)] + pub struct Parsed { + pub options: Vec, +@@ -69,6 +70,7 @@ lazy_static! { + map.insert("flash", HdcCommand::FlashdFlashInit); + map.insert("erase", HdcCommand::FlashdErase); + map.insert("format", HdcCommand::FlashdFormat); ++ map.insert("dumptask", HdcCommand::DumpTask); + + map + }; +@@ -150,7 +152,7 @@ pub fn exchange_parsed_for_daemon(mut parsed: Parsed) -> Parsed { + } + } + parsed.parameters.clear(); +- hdc::info!("parsed parameter is {:?}", parsed.parameters); ++ crate::info!("parsed parameter is {:?}", parsed.parameters); + } + parsed + } +diff --git a/hdc_rust/src/host/server.rs b/hdc_rust/src/host_transfer/server.rs +similarity index 87% +rename from hdc_rust/src/host/server.rs +rename to hdc_rust/src/host_transfer/server.rs +index 2f9d2cad..6cd407ae 100644 +--- a/hdc_rust/src/host/server.rs ++++ b/hdc_rust/src/host_transfer/server.rs +@@ -12,21 +12,21 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +-use crate::parser; +-use crate::task; ++use super::parser; ++use super::task; + #[cfg(target_os = "windows")] + use libc::{c_char, c_int}; + #[cfg(target_os = "windows")] + use std::ffi::CString; + +-use crate::task::ConnectMap; +-use hdc::config; +-use hdc::config::HdcCommand; +-use hdc::host_transfer::host_usb; +-use hdc::transfer; +-use hdc::utils; ++use super::task::ConnectMap; ++use crate::config; ++use crate::config::HdcCommand; ++use crate::host_transfer::host_usb; ++use crate::transfer; ++use crate::utils; + #[allow(unused)] +-use hdc::utils::hdc_log::*; ++use crate::utils::hdc_log::*; + use std::io::{self, Error, ErrorKind}; + use std::process; + use std::str::FromStr; +@@ -86,7 +86,7 @@ async fn start_usb_server() { + if sn.is_empty() { + continue; + } +- hdc::info!("start_usb_server sn:{}", sn); ++ crate::info!("start_usb_server sn:{}", sn); + task::start_usb_device_loop(ptr, sn.to_string()).await; + } + std::thread::sleep(Duration::from_millis(WAIT_TIME_MS)); +@@ -102,11 +102,11 @@ async fn start_usb_server() { + async fn start_client_listen(addr_str: String) -> io::Result<()> { + let saddr = addr_str; + let listener = TcpListener::bind(saddr.clone()).await?; +- hdc::info!("server binds on {saddr}"); ++ crate::info!("server binds on {saddr}"); + + loop { + let (stream, addr) = listener.accept().await?; +- hdc::info!("accepted client {addr}"); ++ crate::info!("accepted client {addr}"); + ylong_runtime::spawn(handle_client(stream)); + } + } +@@ -128,7 +128,7 @@ pub async fn get_process_pids() -> Vec { + get_pid = false; + }, + Err(err) => { +- hdc::error!("'{token}' to u32 failed, {err}"); ++ crate::error!("'{token}' to u32 failed, {err}"); + continue; + }, + } +@@ -147,7 +147,7 @@ pub async fn get_process_pids() -> Vec { + let output_str = String::from_utf8_lossy(&output_vec); + for pid_str in output_str.split_whitespace() { + let Ok(pid) = u32::from_str(pid_str) else { +- hdc::error!("'{pid_str}' to u32 error"); ++ crate::error!("'{pid_str}' to u32 error"); + continue; + }; + pids.push(pid); +@@ -162,16 +162,16 @@ pub async fn server_fork(addr_str: String, log_level: usize) { + let current_exe = match std::env::current_exe() { + Ok(current_exe) => current_exe, + Err(err) => { +- hdc::error!("server_fork, {err}"); ++ crate::error!("server_fork, {err}"); + return; + } + }; + let Ok(run_path) = CString::new(current_exe.display().to_string()) else { +- hdc::error!("server_fork CString::new fail"); ++ crate::error!("server_fork CString::new fail"); + return; + }; + let Ok(listen_string) = CString::new(addr_str) else { +- hdc::error!("server_fork CString::new fail"); ++ crate::error!("server_fork CString::new fail"); + return; + }; + if unsafe { +@@ -183,7 +183,7 @@ pub async fn server_fork(addr_str: String, log_level: usize) { + } { + ylong_runtime::time::sleep(Duration::from_millis(1000)).await + } else { +- hdc::info!("server fork failed") ++ crate::info!("server fork failed") + } + } + +@@ -192,7 +192,7 @@ pub async fn server_fork(addr_str: String, log_level: usize) { + let current_exe = match std::env::current_exe() { + Ok(current_exe) => current_exe.display().to_string(), + Err(err) => { +- hdc::error!("server_fork, {err}"); ++ crate::error!("server_fork, {err}"); + return; + } + }; +@@ -208,7 +208,7 @@ pub async fn server_fork(addr_str: String, log_level: usize) { + .spawn(); + match result { + Ok(_) => ylong_runtime::time::sleep(Duration::from_millis(1000)).await, +- Err(_) => hdc::info!("server fork failed"), ++ Err(_) => crate::info!("server fork failed"), + } + } + +@@ -221,12 +221,12 @@ pub async fn server_kill() { + if cfg!(target_os = "windows") { + match utils::execute_cmd(format!("taskkill /pid {} /f", pid)) { + Ok(_) => println!("Kill server finish"), +- Err(e) => hdc::info!("Kill server error {}", e.to_string()), ++ Err(e) => crate::info!("Kill server error {}", e.to_string()), + }; + } else { + match utils::execute_cmd(format!("kill -9 {}", pid)) { + Ok(_) => println!("Kill server finish"), +- Err(e) => hdc::info!("Kill server error {}", e.to_string()), ++ Err(e) => crate::info!("Kill server error {}", e.to_string()), + }; + } + } +@@ -255,7 +255,7 @@ async fn handle_client(stream: TcpStream) -> io::Result<()> { + set_target_status(TargetStatus::NotReadyAndUnknown); + } + if target_list.is_empty() && is_target_status_equal(TargetStatus::NotReadyAndUnknown) { +- hdc::warn!("found no targets."); ++ crate::warn!("found no targets."); + std::thread::sleep(Duration::from_millis(WAIT_TIME_MS)); + retry_count += 1; + if retry_count >= RETRY_MAX_COUNT { +@@ -270,14 +270,14 @@ async fn handle_client(stream: TcpStream) -> io::Result<()> { + let recv = match transfer::tcp::recv_channel_message(&mut rd).await { + Ok(recv) => recv, + Err(err) => { +- hdc::error!("recv_channel_message failed, {err}"); ++ crate::error!("recv_channel_message failed, {err}"); + return Ok(()); + } + }; +- hdc::debug!("recv hex: {}", recv.iter().map(|c| format!("{c:02x}")).collect::>().join(" ")); ++ crate::debug!("recv hex: {}", recv.iter().map(|c| format!("{c:02x}")).collect::>().join(" ")); + + let recv_str = String::from_utf8_lossy(&recv.clone()).into_owned(); +- hdc::debug!("recv str: {}", recv_str.clone()); ++ crate::debug!("recv str: {}", recv_str.clone()); + let mut parsed = parser::split_opt_and_cmd( + String::from_utf8_lossy(&recv) + .into_owned() +@@ -298,7 +298,7 @@ async fn handle_client(stream: TcpStream) -> io::Result<()> { + + parsed = parser::exchange_parsed_for_daemon(parsed); + +- hdc::debug!("parsed cmd: {:#?}", parsed); ++ crate::debug!("parsed cmd: {:#?}", parsed); + + if let Some(cmd) = parsed.command { + if let Err(e) = task::channel_task_dispatch(task::TaskInfo { +@@ -309,7 +309,7 @@ async fn handle_client(stream: TcpStream) -> io::Result<()> { + }) + .await + { +- hdc::error!("{e}"); ++ crate::error!("{e}"); + } + } else { + return Err(Error::new(ErrorKind::Other, "command not found")); +@@ -322,7 +322,7 @@ async fn handshake_with_client( + wr: SplitWriteHalf, + ) -> io::Result<(String, u32)> { + let channel_id = utils::get_pseudo_random_u32(); +- transfer::TcpMap::start(channel_id, wr).await; ++ transfer::ChannelTcpMap::start(channel_id, wr).await; + + let buf = [ + config::HANDSHAKE_MESSAGE.as_bytes(), +diff --git a/hdc_rust/src/host/task.rs b/hdc_rust/src/host_transfer/task.rs +similarity index 88% +rename from hdc_rust/src/host/task.rs +rename to hdc_rust/src/host_transfer/task.rs +index 10a1e8ea..d7361f47 100644 +--- a/hdc_rust/src/host/task.rs ++++ b/hdc_rust/src/host_transfer/task.rs +@@ -12,22 +12,23 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +-use crate::auth::{handshake_task, start_handshake_with_daemon}; ++use super::auth::{handshake_task, start_handshake_with_daemon}; + use crate::config::*; +-use crate::host_app; +-use crate::host_app::HostAppTaskMap; +-use hdc::common::forward::{self, ForwardTaskMap, HdcForward}; ++use super::host_app; ++use super::host_app::HostAppTaskMap; ++use crate::common::forward::{self, ForwardTaskMap, HdcForward}; ++use crate::common::context; + /// ActionType 未定义,临时屏蔽 + /// use crate::host_app::HostAppTask; +-/// use hdc::common::hdcfile::HdcFile; +-use hdc::common::hdcfile::{self, FileTaskMap, HdcFile}; +-use hdc::config::{ConnectType, HdcCommand}; +-use hdc::host_transfer::host_usb; +-use hdc::transfer; +-use hdc::transfer::send_channel_data; +-use hdc::utils; ++/// use crate::common::hdcfile::HdcFile; ++use crate::common::hdcfile::{self, FileTaskMap, HdcFile}; ++use crate::config::{ConnectType, HdcCommand}; ++use crate::host_transfer::host_usb; ++use crate::transfer; ++use crate::transfer::send_channel_data; ++use crate::utils; + #[allow(unused)] +-use hdc::utils::hdc_log::*; ++use crate::utils::hdc_log::*; + use std::collections::HashMap; + use std::io::{self, Error, ErrorKind}; + use std::sync::Arc; +@@ -38,7 +39,8 @@ use ylong_runtime::net::SplitReadHalf; + use ylong_runtime::net::TcpStream; + use ylong_runtime::sync::{Mutex, RwLock, mpsc}; + +-use crate::host_app::HostAppTask; ++use super::host_app::HostAppTask; ++use super::task_manager; + + #[derive(Debug, Clone)] + pub struct TaskInfo { +@@ -49,14 +51,14 @@ pub struct TaskInfo { + } + + pub async fn channel_task_dispatch(task_info: TaskInfo) -> io::Result<()> { +- hdc::debug!( ++ crate::debug!( + "in channel_task_dispatch, task_info={:#?}", + task_info.clone() + ); + + match task_info.command { + HdcCommand::UnityRunmode | HdcCommand::UnityRootrun => { +- hdc::trace!("dispatch to runmode task"); ++ crate::trace!("dispatch to runmode task"); + channel_unity_task(task_info).await? + } + HdcCommand::UnityReboot => { +@@ -66,24 +68,28 @@ pub async fn channel_task_dispatch(task_info: TaskInfo) -> io::Result<()> { + send_to_daemon(task_info, HdcCommand::UnityRemount, 2, false).await?; + } + HdcCommand::UnityExecute | HdcCommand::ShellInit | HdcCommand::ShellData => { +- hdc::trace!("dispatch to shell task"); ++ crate::trace!("dispatch to shell task"); + channel_shell_task(task_info).await? + } + HdcCommand::KernelTargetConnect => { +- hdc::trace!("dispatch to tconn task"); ++ crate::trace!("dispatch to tconn task"); + channel_connect_task(task_info).await?; + } + HdcCommand::KernelTargetList => { +- hdc::trace!("dispatch to list task"); ++ crate::trace!("dispatch to list task"); + channel_list_targets_task(task_info).await?; + } ++ HdcCommand::DumpTask => { ++ crate::trace!("dispatch to dump task"); ++ channel_dump_task(task_info).await?; ++ } + HdcCommand::KernelWaitFor => { +- hdc::trace!("dispatch to wait"); ++ crate::trace!("dispatch to wait"); + channel_wait_for_any(task_info).await?; + } + HdcCommand::KernelChannelClose => { +- hdc::trace!("dispatch to close task"); +- transfer::TcpMap::end(task_info.channel_id).await; ++ crate::trace!("dispatch to close task"); ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + } + HdcCommand::FileInit + | HdcCommand::FileBegin +@@ -132,7 +138,7 @@ pub async fn channel_task_dispatch(task_info: TaskInfo) -> io::Result<()> { + check_server_task(task_info).await?; + } + _ => { +- hdc::info!("get unknown command {:#?}", task_info.command); ++ crate::info!("get unknown command {:#?}", task_info.command); + return Err(Error::new(ErrorKind::Other, "command not found")); + } + } +@@ -159,7 +165,7 @@ async fn channel_forward_task(task_info: TaskInfo) -> io::Result<()> { + return Ok(()); + } + _ => { +- hdc::warn!("channel_forward_task, other commands"); ++ crate::warn!("channel_forward_task, other commands"); + } + } + Ok(()) +@@ -169,14 +175,14 @@ async fn channel_forward_remove(task_info: TaskInfo, forward_or_reverse: bool) - + let task_string = task_info.params[2..].join(" ").clone(); + let session_id = + get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; +- hdc::info!( ++ crate::info!( + "channel_forward_remove task_string:{}, session_id:{}", + task_string, + session_id + ); + let _result = + forward::HdcForwardInfoMap::remove_forward(task_string.clone(), forward_or_reverse).await; +- hdc::info!("channel_forward_remove remove result:{}", _result); ++ crate::info!("channel_forward_remove remove result:{}", _result); + if !_result { + let message_str = format!("Remove forward ruler failed, ruler is not exist {}", task_string); + let _ = transfer::send_channel_msg( +@@ -185,7 +191,7 @@ async fn channel_forward_remove(task_info: TaskInfo, forward_or_reverse: bool) - + message_str, + ) + .await; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + return Ok(()); + } + let forward_channel_id = forward::ForwardTaskMap::get_channel_id(session_id, task_string.clone()).await; +@@ -198,7 +204,7 @@ async fn channel_forward_remove(task_info: TaskInfo, forward_or_reverse: bool) - + message_str.as_bytes().to_vec(), + ) + .await; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + Ok(()) + } + +@@ -206,7 +212,7 @@ async fn channel_forward_list(task_info: TaskInfo, forward_or_reverse: bool) -> + let mut result = forward::HdcForwardInfoMap::get_all_forward_infos().await; + if result.is_empty() { + send_channel_data(task_info.channel_id, "[Empty]".as_bytes().to_vec()).await; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + return Ok(()); + } + for item in &mut result { +@@ -234,7 +240,7 @@ async fn channel_forward_list(task_info: TaskInfo, forward_or_reverse: bool) -> + result_str.push_str(&line); + } + send_channel_data(task_info.channel_id, result_str.as_bytes().to_vec()).await; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + Ok(()) + } + +@@ -346,7 +352,7 @@ async fn channel_file_task(task_info: TaskInfo) -> io::Result<()> { + return Ok(()); + } + _ => { +- hdc::info!("other tasks, payload is {:#?}", payload); ++ crate::info!("other tasks, payload is {:#?}", payload); + } + } + Ok(()) +@@ -355,7 +361,7 @@ async fn channel_file_task(task_info: TaskInfo) -> io::Result<()> { + async fn send_to_daemon(task_info: TaskInfo, _cmd: HdcCommand, param_start_idx: usize, async_flag: bool) -> io::Result<()> { + let session_id = + get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; +- hdc::info!("task_info params is {:?}", task_info); ++ crate::info!("task_info params is {:?}", task_info); + transfer::put( + session_id, + TaskMessage { +@@ -366,7 +372,7 @@ async fn send_to_daemon(task_info: TaskInfo, _cmd: HdcCommand, param_start_idx: + ) + .await; + if async_flag { +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + } + Ok(()) + } +@@ -453,7 +459,7 @@ async fn channel_connect_task(task_info: TaskInfo) -> io::Result<()> { + "Target is connected, repeat operation".to_string(), + ) + .await; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + return ret; + } + start_tcp_daemon_session(connect_key, &task_info).await +@@ -463,18 +469,18 @@ pub async fn usb_handle_deamon(ptr: u64, mut rx: mpsc::BoundedReceiver<(TaskMess + loop { + match rx.recv().await { + Ok((task_message, _index)) => { +- hdc::debug!( ++ crate::debug!( + "in usb_handle_deamon, recv cmd: {:#?}, payload len: {}", + task_message.command, + task_message.payload.len(), + ); + if let Err(e) = session_task_dispatch(task_message, session_id, connect_key.clone()).await { +- hdc::error!("dispatch task failed: {}", e.to_string()); ++ crate::error!("dispatch task failed: {}", e.to_string()); + } + } + Err(e) => { +- hdc::warn!("unpack task failed: {}", e.to_string()); +- ConnectMap::remove(connect_key.clone()).await; ++ crate::warn!("unpack task failed: {}", e.to_string()); ++ task_manager::free_session(session_id).await; + host_usb::on_device_connected(ptr, connect_key, false); + return Err(Error::new(ErrorKind::Other, "recv error")); + } +@@ -491,7 +497,7 @@ pub async fn start_usb_device_loop(ptr: u64, connect_key: String) { + host_usb::HostUsbMap::start(session_id, wr).await; + let rx = host_usb::start_recv(ptr, connect_key.clone(), session_id); + let channel_id = utils::get_pseudo_random_u32(); +- hdc::info!("generate new session {} channel {}", session_id, channel_id); ++ crate::info!("generate new session {} channel {}", session_id, channel_id); + start_handshake_with_daemon(connect_key.clone(), session_id, channel_id, ConnectType::HostUsb(connect_key.clone())).await; + let _ = ylong_runtime::spawn(usb_handle_deamon(ptr, rx, session_id, connect_key)).await; + } +@@ -505,7 +511,7 @@ async fn start_tcp_daemon_session(connect_key: String, task_info: &TaskInfo) -> + "Connect to daemon failed".to_string(), + ) + .await; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + ret + } + Ok(stream) => { +@@ -521,7 +527,7 @@ async fn start_tcp_daemon_session(connect_key: String, task_info: &TaskInfo) -> + "Connect OK".to_string(), + ) + .await?; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + Ok(()) + } + } +@@ -536,7 +542,14 @@ async fn channel_list_targets_task(task_info: TaskInfo) -> io::Result<()> { + target_list.join("\n") + }; + transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; ++ Ok(()) ++} ++ ++async fn channel_dump_task(task_info: TaskInfo) -> io::Result<()> { ++ let msg = task_manager::dump_running_task_info().await; ++ transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + Ok(()) + } + +@@ -544,26 +557,26 @@ async fn channel_list_targets_task(task_info: TaskInfo) -> io::Result<()> { + async fn channel_wait_for_any(task_info: TaskInfo) -> io::Result<()> { + let target_list = ConnectMap::get_list(false).await; + if target_list.is_empty() { +- hdc::info!("No any connected target"); ++ crate::info!("No any connected target"); + let msg = "No connected target".to_string(); + transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; + } else if task_info.connect_key == "any" { +- hdc::info!("Wait for connected target any"); ++ crate::info!("Wait for connected target any"); + let msg = "Wait for connected target any get ".to_string() + target_list[0].as_str(); + transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + } else { + // wait for special connectkey + if target_list + .iter() + .any(|connect_key| connect_key == &task_info.connect_key) + { +- hdc::info!("Wait for connected target is {}", task_info.connect_key); ++ crate::info!("Wait for connected target is {}", task_info.connect_key); + let msg = "Wait for connected target is ".to_string() + task_info.connect_key.as_str(); + transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; +- transfer::TcpMap::end(task_info.channel_id).await; ++ transfer::ChannelTcpMap::end(task_info.channel_id).await; + } else { +- hdc::info!("No {} connected target ", task_info.connect_key); ++ crate::info!("No {} connected target ", task_info.connect_key); + let msg = "No connected target".to_string(); + transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; + } +@@ -579,18 +592,18 @@ async fn tcp_handle_deamon( + loop { + match transfer::tcp::unpack_task_message(&mut rd).await { + Ok(task_message) => { +- // hdc::info!( ++ // crate::info!( + // "in tcp_handle_deamon, recv cmd: {:#?}, payload len: {}", + // task_message.command, + // task_message.payload.len(), + // ); + if let Err(e) = session_task_dispatch(task_message, session_id, connect_key.clone()).await { +- hdc::error!("dispatch task failed: {}", e.to_string()); ++ crate::error!("dispatch task failed: {}", e.to_string()); + } + } + Err(e) => { +- hdc::warn!("unpack task failed: {}", e.to_string()); +- ConnectMap::remove(connect_key).await; ++ crate::warn!("unpack task failed: {}", e.to_string()); ++ task_manager::free_session(session_id).await; + return Err(e); + } + }; +@@ -610,7 +623,7 @@ async fn session_task_dispatch(task_message: TaskMessage, session_id: u32, conne + level, + str, + ).await { +- hdc::error!("echo to client failed: {}", e.to_string()); ++ crate::error!("echo to client failed: {}", e.to_string()); + }; + } + } +@@ -716,7 +729,7 @@ async fn session_file_task(task_message: TaskMessage, session_id: u32) -> io::Re + return Ok(()); + } + _ => { +- hdc::info!("other tasks"); ++ crate::info!("other tasks"); + } + } + /* ActionType 未定义,临时屏蔽 +@@ -750,7 +763,7 @@ async fn session_file_task(task_message: TaskMessage, session_id: u32) -> io::Re + e.insert(Arc::new(Mutex::new(task))); + } + _ => { +- hdc::info!("other tasks"); ++ crate::info!("other tasks"); + } + } + } +@@ -771,8 +784,9 @@ pub async fn session_channel_close(task_message: TaskMessage, session_id: u32) - + }; + transfer::put(session_id, message).await; + } +- hdc::info!("recv channel close {}", task_message.channel_id); +- transfer::TcpMap::end(task_message.channel_id).await; ++ crate::info!("recv channel close {}", task_message.channel_id); ++ context::ContextMap::channel_close(session_id, task_message.channel_id).await; ++ transfer::ChannelTcpMap::end(task_message.channel_id).await; + Ok(()) + } + +@@ -822,7 +836,7 @@ impl ConnectMap { + } + } + +- async fn remove(connect_key: String) { ++ pub async fn remove(connect_key: String) { + let instance = Self::get_instance(); + let mut map = instance.write().await; + map.remove(&connect_key); +@@ -835,7 +849,7 @@ impl ConnectMap { + } + + pub async fn update(connect_key: String, +- conn_status: crate::task::ConnectStatus, ++ conn_status: ConnectStatus, + version: String, + dev_name: String, + emg_msg: String, +@@ -941,7 +955,7 @@ async fn get_valid_session_id(connect_key: String, channel_id: u32) -> io::Resul + "Targets not found, please check the connect-key.".to_string(), + ) + .await?; +- transfer::TcpMap::end(channel_id).await; ++ transfer::ChannelTcpMap::end(channel_id).await; + Err(Error::new(ErrorKind::Other, "session not found")) + } + } +diff --git a/hdc_rust/src/host_transfer/task_manager.rs b/hdc_rust/src/host_transfer/task_manager.rs +new file mode 100644 +index 00000000..bca005d1 +--- /dev/null ++++ b/hdc_rust/src/host_transfer/task_manager.rs +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (C) 2024 Huawei Device Co., Ltd. ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++//! task_manager ++use crate::config::*; ++use super::task::ConnectMap; ++use super::host_app; ++use crate::common::hdcfile; ++use crate::common::forward; ++use crate::transfer::{self, ConnectTypeMap, buffer}; ++use crate::host_transfer::host_usb; ++#[allow(unused)] ++use crate::utils::hdc_log::*; ++ ++pub async fn free_session(session_id: u32) { ++ stop_task(session_id).await; ++ if let Some(connect_key) = ConnectMap::get_connect_key(session_id).await { ++ ConnectMap::remove(connect_key).await; ++ } ++ match ConnectTypeMap::get(session_id).await { ++ Some(ConnectType::Bt) => {} ++ Some(ConnectType::Tcp) => { ++ transfer::TcpMap::end(session_id).await; ++ } ++ Some(ConnectType::Uart) => {} ++ Some(ConnectType::Usb(_)) => {} ++ ++ Some(ConnectType::HostUsb(_)) => { ++ host_usb::HostUsbMap::end(session_id).await; ++ } ++ ++ Some(ConnectType::Bridge) => {} ++ ++ None => { ++ crate::warn!("free_session cannot find connect type for session_id:{session_id}"); ++ } ++ } ++} ++ ++pub async fn stop_task(session_id: u32) { ++ hdcfile::stop_task(session_id).await; ++ host_app::stop_task(session_id).await; ++ forward::stop_task(session_id).await; ++} ++ ++pub async fn dump_running_task_info() -> String { ++ let mut result = "".to_string(); ++ result.push_str(&format!("{:#}", buffer::dump_session().await)); ++ result.push_str(&format!("{:#}", hdcfile::dump_task().await)); ++ result.push_str(&format!("{:#}", host_app::dump_task().await)); ++ result.push_str(&format!("{:#}", forward::dump_task().await)); ++ result.to_string() ++} +\ No newline at end of file +diff --git a/hdc_rust/src/host/translate.rs b/hdc_rust/src/host_transfer/translate.rs +similarity index 100% +rename from hdc_rust/src/host/translate.rs +rename to hdc_rust/src/host_transfer/translate.rs +diff --git a/hdc_rust/src/host/tty_utility.rs b/hdc_rust/src/host_transfer/tty_utility.rs +similarity index 94% +rename from hdc_rust/src/host/tty_utility.rs +rename to hdc_rust/src/host_transfer/tty_utility.rs +index 5f4d0cd1..124cd67b 100644 +--- a/hdc_rust/src/host/tty_utility.rs ++++ b/hdc_rust/src/host_transfer/tty_utility.rs +@@ -16,7 +16,8 @@ + + #[cfg(target_os = "windows")] + use std::collections::HashMap; +- ++#[allow(unused)] ++use lazy_static::lazy_static; + #[cfg(target_os = "windows")] + extern "C" { + fn getch() -> libc::c_int; +@@ -61,7 +62,7 @@ pub fn convert_to_control_code() -> Vec { + unicode_byte.push(c as u8); + } + } +- None => hdc::info!("current control code is not support now"), ++ None => crate::info!("current control code is not support now"), + } + + unicode_byte +@@ -89,7 +90,7 @@ fn get_unicode_len(input_char: i32) -> u32 { + // 通过第一个字符判断unicode长度,并读取组装完成的unicode + pub fn unicode_assemble(first_char: i32) -> Vec { + let mut len = get_unicode_len(first_char); +- hdc::info!("unicode bytes len is {:?}", len); ++ crate::info!("unicode bytes len is {:?}", len); + + let mut unicode_byte: Vec = Vec::new(); + unicode_byte.push(first_char as u8); +diff --git a/hdc_rust/src/host/unittest.rs b/hdc_rust/src/host_transfer/unittest.rs +similarity index 100% +rename from hdc_rust/src/host/unittest.rs +rename to hdc_rust/src/host_transfer/unittest.rs +diff --git a/hdc_rust/src/lib.rs b/hdc_rust/src/lib.rs +index 5559b89d..660fcbe2 100644 +--- a/hdc_rust/src/lib.rs ++++ b/hdc_rust/src/lib.rs +@@ -20,6 +20,8 @@ pub mod common; + pub mod config; + #[cfg(not(feature = "host"))] + pub mod daemon_lib; ++#[cfg(not(feature = "host"))] ++pub mod daemon_transfer; + #[cfg(feature = "host")] + pub mod host_transfer; + pub mod serializer; +diff --git a/hdc_rust/src/transfer.rs b/hdc_rust/src/transfer.rs +index 0c3a60b0..c6d3b67f 100644 +--- a/hdc_rust/src/transfer.rs ++++ b/hdc_rust/src/transfer.rs +@@ -19,17 +19,15 @@ pub mod buffer; + pub mod tcp; + pub mod uart; + pub mod uart_wrapper; +-pub mod usb; + pub use buffer::dump_session; + pub use buffer::put; + pub use buffer::send_channel_data; + pub use buffer::send_channel_msg; +-pub use buffer::usb_start_recv; + pub use buffer::ChannelMap; ++pub use buffer::ChannelTcpMap; + pub use buffer::EchoLevel; + pub use buffer::TcpMap; + pub use buffer::UartMap; +-pub use buffer::UsbMap; + pub use buffer::ConnectTypeMap; + pub use uart::uart_close; + pub use uart_wrapper::start_session; +diff --git a/hdc_rust/src/transfer/base.rs b/hdc_rust/src/transfer/base.rs +index b26d97c8..64e1a7d0 100644 +--- a/hdc_rust/src/transfer/base.rs ++++ b/hdc_rust/src/transfer/base.rs +@@ -165,68 +165,3 @@ pub async fn unpack_task_message_lock( + } + } + } +- +-pub fn unpack_task_message( +- rd: &mut dyn Reader, +- tx: BoundedSender<(TaskMessage, u32, u32)>, +-) -> io::Result<()> { +- let (pack_size, package_index, session_id) = rd.check_protocol_head()?; +- if pack_size == 0 { +- return Ok(()); +- } +- +- let data = rd.read_frame(pack_size as usize)?; +- ylong_runtime::spawn(async move { +- let (head, body) = data.split_at(serializer::HEAD_SIZE); +- let payload_head = serializer::unpack_payload_head(head.to_vec()); +- match payload_head { +- Ok(payload_head) => { +- let expected_head_size = u16::from_be(payload_head.head_size) as usize; +- let expected_data_size = u32::from_be(payload_head.data_size) as usize; +- +- if serializer::HEAD_SIZE + expected_head_size + expected_data_size != pack_size as usize { +- crate::warn!( +- "protocol size diff: {pack_size} != {} + {expected_head_size} + {expected_data_size}", +- serializer::HEAD_SIZE +- ); +- } +- +- if expected_head_size + expected_data_size == 0 +- || expected_head_size + expected_data_size > HDC_BUF_MAX_SIZE +- { +- return Err(Error::new(ErrorKind::Other, "Packet size incorrect")); +- } +- +- let (protect, payload) = body.split_at(expected_head_size); +- +- let payload_protect = serializer::unpack_payload_protect(protect.to_vec())?; +- let channel_id = payload_protect.channel_id; +- +- let command = match HdcCommand::try_from(payload_protect.command_flag) { +- Ok(command) => command, +- Err(_) => { +- return Err(Error::new(ErrorKind::Other, "unknown command")); +- } +- }; +- +- let _ = tx +- .send(( +- TaskMessage { +- channel_id, +- command, +- payload: payload.to_vec(), +- }, +- package_index, +- session_id, +- )) +- .await; +- Ok(()) +- } +- Err(e) => { +- Err(utils::error_other(format!("usb unpack_task_message, err:{:?}", e))) +- } +- } +- }); +- +- Ok(()) +-} +diff --git a/hdc_rust/src/transfer/buffer.rs b/hdc_rust/src/transfer/buffer.rs +index 3c56454c..f60044af 100644 +--- a/hdc_rust/src/transfer/buffer.rs ++++ b/hdc_rust/src/transfer/buffer.rs +@@ -15,14 +15,17 @@ + //! buffer + #![allow(missing_docs)] + +-use super::base::{self, Writer}; ++use super::base::Writer; + use super::uart::UartWriter; +-use super::usb::{self, UsbReader, UsbWriter}; + use super::{tcp, uart_wrapper}; + #[cfg(feature = "emulator")] + use crate::daemon_lib::bridge::BridgeMap; + #[cfg(feature = "host")] + use crate::host_transfer::host_usb::HostUsbMap; ++#[cfg(feature = "host")] ++use crate::host_transfer::task_manager; ++#[cfg(not(feature = "host"))] ++use crate::daemon_transfer::usb::UsbMap; + + use crate::config::TaskMessage; + use crate::config::{self, ConnectType}; +@@ -36,14 +39,12 @@ use std::io::{self, Error, ErrorKind}; + use std::sync::Arc; + use std::sync::Once; + use std::mem::MaybeUninit; +-use crate::transfer::usb::usb_write_all; +-use std::time::Duration; + + #[cfg(feature = "host")] + extern crate ylong_runtime_static as ylong_runtime; + use ylong_runtime::io::AsyncWriteExt; + use ylong_runtime::net::{SplitReadHalf, SplitWriteHalf}; +-use ylong_runtime::sync::{mpsc, Mutex, RwLock}; ++use ylong_runtime::sync::{Mutex, RwLock}; + + type ConnectTypeMap_ = Arc>>; + +@@ -138,29 +139,6 @@ impl TcpMap { + let _ = wr.write_all(send.as_slice()).await; + } + +- pub async fn send_channel_message(channel_id: u32, buf: Vec) -> io::Result<()> { +- crate::trace!( +- "send channel({channel_id}) msg: {:?}", +- buf.iter() +- .map(|&c| format!("{c:02X}")) +- .collect::>() +- .join(" ") +- ); +- let send = [ +- u32::to_be_bytes(buf.len() as u32).as_slice(), +- buf.as_slice(), +- ] +- .concat(); +- let instance = Self::get_instance(); +- let map = instance.map.lock().await; +- if let Some(guard) = map.get(&channel_id) { +- let mut wr = guard.lock().await; +- let _ = wr.write_all(send.as_slice()).await; +- return Ok(()); +- } +- Err(Error::new(ErrorKind::NotFound, "channel not found")) +- } +- + pub async fn start(id: u32, wr: SplitWriteHalf) { + let instance = Self::get_instance(); + let mut map = instance.map.lock().await; +@@ -182,123 +160,6 @@ impl TcpMap { + } + } + +-pub struct UsbMap { +- map: std::sync::Mutex>, +- lock: std::sync::Mutex, +-} +-impl UsbMap { +- pub(crate) fn get_instance() -> &'static UsbMap { +- static mut USB_MAP: MaybeUninit = MaybeUninit::uninit(); +- static ONCE: Once = Once::new(); +- +- unsafe { +- ONCE.call_once(|| { +- let global = UsbMap { +- map: std::sync::Mutex::new(HashMap::new()), +- lock: std::sync::Mutex::new(0) +- }; +- USB_MAP = MaybeUninit::new(global); +- }); +- &*USB_MAP.as_ptr() +- } +- } +- +- #[allow(unused)] +- async fn put(session_id: u32, data: TaskMessage) -> io::Result<()> { +- if DiedSession::get(session_id).await { +- return Err(Error::new(ErrorKind::NotFound, "session already died"));; +- } +- let mut fd = 0; +- { +- let instance = Self::get_instance(); +- let mut map = instance.map.lock().unwrap(); +- let Some(arc_wr) = map.get(&session_id) else { +- return Err(Error::new(ErrorKind::NotFound, "session not found")); +- }; +- fd =arc_wr.fd; +- } +- let body = serializer::concat_pack(data); +- let head = usb::build_header(session_id, 1, body.len()); +- let instance = Self::get_instance(); +- let _guard = instance.lock.lock().unwrap(); +- let mut child_ret = 0; +- match usb_write_all(fd, head) { +- Ok(_) => {} +- Err(e) => { +- return Err(Error::new(ErrorKind::Other, "Error writing head")); +- } +- } +- +- match usb_write_all(fd, body) { +- Ok(ret) => { +- child_ret = ret; +- } +- Err(e) => { +- return Err(Error::new(ErrorKind::Other, "Error writing body")); +- } +- } +- +- if ((child_ret % config::MAX_PACKET_SIZE_HISPEED) == 0) && (child_ret > 0) { +- let tail = usb::build_header(session_id, 0, 0); +- // win32 send ZLP will block winusb driver and LIBUSB_TRANSFER_ADD_ZERO_PACKET not effect +- // so, we send dummy packet to prevent zero packet generate +- match usb_write_all(fd, tail) { +- Ok(_) => {} +- Err(e) => { +- return Err(Error::new(ErrorKind::Other, "Error writing tail")); +- } +- } +- } +- Ok(()) +- } +- +- pub async fn start(session_id: u32, wr: UsbWriter) { +- let buffer_map = Self::get_instance(); +- let mut try_times = 0; +- let max_try_time = 10; +- let wait_one_seconds = 1000; +- loop { +- try_times += 1; +- if let Ok(mut map) = buffer_map.map.try_lock() { +- map.insert(session_id, wr); +- crate::error!("start usb session_id:{session_id} get lock success after try {try_times} times"); +- break; +- } else { +- if try_times > max_try_time { +- crate::error!("start usb session_id:{session_id} get lock failed will restart hdcd"); +- std::process::exit(0); +- } +- crate::error!("start usb session_id:{session_id} try lock failed {try_times} times"); +- std::thread::sleep(Duration::from_millis(wait_one_seconds)); +- } +- } +- ConnectTypeMap::put(session_id, ConnectType::Usb("some_mount_point".to_string())).await; +- } +- +- pub async fn end(session_id: u32) { +- let buffer_map = Self::get_instance(); +- let mut try_times = 0; +- let max_try_time = 10; +- let wait_ten_ms = 10; +- loop { +- try_times += 1; +- if let Ok(mut map) = buffer_map.map.try_lock() { +- let _ = map.remove(&session_id); +- crate::error!("end usb session_id:{session_id} get lock success after try {try_times} times"); +- break; +- } else { +- if try_times > max_try_time { +- crate::error!("end usb session_id:{session_id} get lock failed will force break"); +- break; +- } +- crate::warn!("end usb session_id:{session_id} get lock failed {try_times} times"); +- std::thread::sleep(Duration::from_millis(wait_ten_ms)); +- } +- } +- ConnectTypeMap::del(session_id).await; +- } +-} +- + type UartWriter_ = Arc>; + type UartMap_ = Arc>>; + +@@ -344,6 +205,7 @@ pub async fn put(session_id: u32, data: TaskMessage) { + TcpMap::put(session_id, data).await; + } + Some(ConnectType::Usb(_mount_point)) => { ++ #[cfg(not(feature = "host"))] + if let Err(e) = UsbMap::put(session_id, data).await { + crate::error!("{e:?}"); + #[cfg(not(feature = "host"))] +@@ -362,6 +224,8 @@ pub async fn put(session_id: u32, data: TaskMessage) { + #[cfg(feature = "host")] + if let Err(e) = HostUsbMap::put(session_id, data).await { + crate::error!("{e:?}"); ++ #[cfg(feature = "host")] ++ task_manager::free_session(session_id).await; + } + } + None => { +@@ -371,7 +235,7 @@ pub async fn put(session_id: u32, data: TaskMessage) { + } + + pub async fn send_channel_data(channel_id: u32, data: Vec) { +- let _ = TcpMap::send_channel_message(channel_id, data).await; ++ let _ = ChannelTcpMap::send_channel_message(channel_id, data).await; + } + + pub enum EchoLevel { +@@ -399,7 +263,7 @@ pub async fn send_channel_msg(channel_id: u32, level: EchoLevel, msg: String) -> + EchoLevel::RAW => msg.to_string() + "\r\n", + EchoLevel::OK => msg.to_string(), + }; +- TcpMap::send_channel_message(channel_id, data.as_bytes().to_vec()).await ++ ChannelTcpMap::send_channel_message(channel_id, data.as_bytes().to_vec()).await + } + + // client recv and print msg +@@ -435,18 +299,68 @@ impl ChannelMap { + } + } + +-pub fn usb_start_recv(fd: i32, _session_id: u32) -> mpsc::BoundedReceiver<(TaskMessage, u32, u32)> { +- let (tx, rx) = mpsc::bounded_channel::<(TaskMessage, u32, u32)>(config::USB_QUEUE_LEN); +- ylong_runtime::spawn(async move { +- let mut rd = UsbReader { fd }; +- loop { +- if let Err(e) = base::unpack_task_message(&mut rd, tx.clone()) { +- crate::warn!("unpack task failed: {}, reopen fd...", e.to_string()); +- break; +- } ++ ++type ChannelTcpWriter_ = Arc>; ++ ++pub struct ChannelTcpMap { ++ map: Mutex>, ++} ++impl ChannelTcpMap { ++ pub(crate) fn get_instance() -> &'static ChannelTcpMap { ++ static mut CHANNEL_TCP_MAP: MaybeUninit = MaybeUninit::uninit(); ++ static ONCE: Once = Once::new(); ++ ++ unsafe { ++ ONCE.call_once(|| { ++ let global = ChannelTcpMap { ++ map: Mutex::new(HashMap::new()) ++ }; ++ CHANNEL_TCP_MAP = MaybeUninit::new(global); ++ }); ++ &*CHANNEL_TCP_MAP.as_ptr() ++ } ++ } ++ ++ pub async fn send_channel_message(channel_id: u32, buf: Vec) -> io::Result<()> { ++ crate::trace!( ++ "send channel({channel_id}) msg: {:?}", ++ buf.iter() ++ .map(|&c| format!("{c:02X}")) ++ .collect::>() ++ .join(" ") ++ ); ++ let send = [ ++ u32::to_be_bytes(buf.len() as u32).as_slice(), ++ buf.as_slice(), ++ ] ++ .concat(); ++ let instance = Self::get_instance(); ++ let map = instance.map.lock().await; ++ if let Some(guard) = map.get(&channel_id) { ++ let mut wr = guard.lock().await; ++ let _ = wr.write_all(send.as_slice()).await; ++ return Ok(()); ++ } ++ Err(Error::new(ErrorKind::NotFound, "channel not found")) ++ } ++ ++ pub async fn start(id: u32, wr: SplitWriteHalf) { ++ let instance = Self::get_instance(); ++ let mut map = instance.map.lock().await; ++ let arc_wr = Arc::new(Mutex::new(wr)); ++ map.insert(id, arc_wr); ++ crate::warn!("channel tcp start {id}"); ++ } ++ ++ pub async fn end(id: u32) { ++ let instance = Self::get_instance(); ++ let mut map = instance.map.lock().await; ++ if let Some(arc_wr) = map.remove(&id) { ++ let mut wr = arc_wr.lock().await; ++ let _ = wr.shutdown().await; + } +- }); +- rx ++ crate::warn!("channel tcp end {id}"); ++ } + } + + pub struct DiedSession { +diff --git a/hdc_rust/src/transfer/usb.rs b/hdc_rust/src/transfer/usb.rs +deleted file mode 100644 +index 870cfe3f..00000000 +--- a/hdc_rust/src/transfer/usb.rs ++++ /dev/null +@@ -1,224 +0,0 @@ +-/* +- * Copyright (C) 2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +-//! usb +-#![allow(missing_docs)] +- +-use super::base; +- +-use crate::config; +-use crate::serializer; +-use crate::serializer::native_struct::UsbHead; +-use crate::serializer::pack_struct::UsbHeadPack; +-use crate::serializer::serialize::Serialization; +-use crate::serializer::serialize::SerializedBuffer; +-use crate::utils; +-#[allow(unused)] +-use crate::utils::hdc_log::*; +- +-#[cfg(not(target_os = "windows"))] +-use std::ffi::{CStr, CString}; +-use std::io::{self, Error, ErrorKind}; +-#[cfg(not(feature = "host"))] +-use libc::{fcntl, F_SETFD, FD_CLOEXEC}; +- +-#[repr(C)] +-pub struct PersistBuffer { +- pub ptr: *const libc::c_char, +- pub size: libc::c_ulonglong, +-} +- +-pub fn buf_to_vec(buf: PersistBuffer) -> Vec { +- let slice = +- unsafe { std::slice::from_raw_parts(buf.ptr as *const libc::c_uchar, buf.size as usize) }; +- slice.to_vec() +-} +- +-#[allow(unused)] +-extern "C" { +- fn access(_name: *const libc::c_char, _type: i32) -> i32; +- fn free(ptr: *const libc::c_void); +- +- fn ConfigEpPointEx(path: *const libc::c_char) -> i32; +- fn OpenEpPointEx(path: *const libc::c_char) -> i32; +- fn CloseUsbFdEx(fd: i32) -> i32; +- fn CloseEndPointEx(bulkIn: i32, bulkOut: i32, ctrlEp: i32, closeCtrlEp: u8); +- #[cfg(not(target_os = "windows"))] +- fn WriteUsbDevEx(bulkOut: i32, buf: SerializedBuffer) -> i32; +- #[cfg(not(target_os = "windows"))] +- fn ReadUsbDevEx(bulkIn: i32, buf: *mut u8, size: usize) -> usize; +- fn GetDevPathEx(path: *const libc::c_char) -> *const libc::c_char; +- +- fn SerializeUsbHead(value: *const UsbHeadPack) -> SerializedBuffer; +- fn ParseUsbHead(value: *mut UsbHeadPack, buf: SerializedBuffer) -> libc::c_uchar; +-} +- +-#[cfg(not(target_os = "windows"))] +-pub fn usb_init() -> io::Result<(i32, i32, i32)> { +- crate::info!("opening usb fd..."); +- let path = CString::new(config::USB_FFS_BASE).unwrap(); +- +- let base_path = unsafe { +- let p = GetDevPathEx(path.as_ptr()); +- let c_str = CStr::from_ptr(p); +- c_str.to_str().unwrap().to_string() +- }; +- // let c_str: &CStr = unsafe { CStr::from_ptr(p) }; +- // c_str.to_str().unwrap().to_string() +- // let base_path = serializer::ptr_to_string(unsafe { GetDevPathEx(path.as_ptr()) }); +- let ep0 = CString::new(base_path.clone() + "/ep0").unwrap(); +- let ep1 = CString::new(base_path.clone() + "/ep1").unwrap(); +- let ep2 = CString::new(base_path + "/ep2").unwrap(); +- if unsafe { access(ep0.as_ptr(), 0) } != 0 { +- return Err(utils::error_other("cannot access usb path".to_string())); +- } +- +- let config_fd = unsafe { ConfigEpPointEx(ep0.as_ptr()) }; +- if config_fd < 0 { +- return Err(utils::error_other("cannot open usb ep0".to_string())); +- } +- +- let bulkin_fd = unsafe { OpenEpPointEx(ep1.as_ptr()) }; +- if bulkin_fd < 0 { +- return Err(utils::error_other("cannot open usb ep1".to_string())); +- } +- +- let bulkout_fd = unsafe { OpenEpPointEx(ep2.as_ptr()) }; +- if bulkout_fd < 0 { +- return Err(utils::error_other("cannot open usb ep2".to_string())); +- } +- #[cfg(not(feature = "host"))] +- unsafe{ +- // cannot open with O_CLOEXEC, must fcntl +- fcntl(config_fd, F_SETFD, FD_CLOEXEC); +- fcntl(bulkin_fd, F_SETFD, FD_CLOEXEC); +- fcntl(bulkout_fd, F_SETFD, FD_CLOEXEC); +- } +- +- crate::info!("usb fd: {config_fd}, {bulkin_fd}, {bulkout_fd}"); +- +- Ok((config_fd, bulkin_fd, bulkout_fd)) +-} +- +-#[cfg(not(target_os = "windows"))] +-pub fn usb_close(config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) { +- crate::info!("closing usb fd..."); +- unsafe { +- CloseUsbFdEx(config_fd); +- CloseUsbFdEx(bulkin_fd); +- CloseUsbFdEx(bulkout_fd); +- } +-} +- +-pub struct UsbReader { +- pub fd: i32, +-} +-pub struct UsbWriter { +- pub fd: i32, +-} +- +-impl base::Reader for UsbReader { +- // 屏蔽window编译报错 +- #[cfg(not(target_os = "windows"))] +- fn read_frame(&self, expect: usize) -> io::Result> { +- let mut buf :Vec = Vec::with_capacity(expect); +- unsafe { +- let readed = ReadUsbDevEx(self.fd, buf.as_mut_ptr() as *mut libc::uint8_t, expect); +- if readed != expect { +- Err( +- utils::error_other( +- format!( +- "usb read error, usb read failed: expect: {} acture: {}", +- expect, +- readed, +- ) +- ) +- ) +- } else { +- buf.set_len(readed); +- Ok(buf) +- } +- } +- } +- +- // 屏蔽window编译报错 +- #[cfg(target_os = "windows")] +- fn read_frame(&self, _expected_size: usize) -> io::Result> { +- Err(utils::error_other("usb read error".to_string())) +- } +- +- fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> { +- let buf = self.read_frame(serializer::USB_HEAD_SIZE)?; +- if buf[..config::USB_PACKET_FLAG.len()] != config::USB_PACKET_FLAG[..] { +- return Err(Error::new( +- ErrorKind::Other, +- format!("USB_PACKET_FLAG incorrect, content: {:#?}", buf), +- )); +- } +- let mut head = serializer::native_struct::UsbHead::default(); +- +- if let Err(e) = head.parse(buf) { +- crate::warn!("parse usb head error: {}", e.to_string()); +- return Err(e); +- } +- Ok((u32::from_be(head.data_size), 0, u32::to_be(head.session_id))) +- } +-} +- +-#[cfg(not(target_os = "windows"))] +-pub fn usb_write_all(fd: i32, data: Vec) -> io::Result { +- let buf = SerializedBuffer { +- ptr: data.as_ptr() as *const libc::c_char, +- size: data.len() as u64, +- }; +- let ret = unsafe { WriteUsbDevEx(fd, buf) } as i32; +- if ret < 0 { +- Err(utils::error_other("usb write failed".to_string())) +- } else { +- Ok(ret) +- } +-} +-impl base::Writer for UsbWriter { +- // 屏蔽window编译报错 +- #[cfg(not(target_os = "windows"))] +- #[allow(unused)] +- fn write_all(&self, data: Vec) -> io::Result { +- let buf = SerializedBuffer { +- ptr: data.as_ptr() as *const libc::c_char, +- size: data.len() as u64, +- }; +- let ret = unsafe { WriteUsbDevEx(self.fd, buf) } as i32; +- if ret < 0 { +- Err(utils::error_other("usb write failed".to_string())) +- } else { +- Ok(ret) +- } +- } +- +- // 屏蔽window编译报错 +- #[cfg(target_os = "windows")] +- fn write_all(&self, _data: Vec) -> io::Result { +- Ok(0) +- } +-} +- +-pub fn build_header(session_id: u32, option: u8, length: usize) -> Vec { +- UsbHead { +- session_id: u32::to_be(session_id), +- flag: [config::USB_PACKET_FLAG[0], config::USB_PACKET_FLAG[1]], +- option, +- data_size: u32::to_be(length as u32), +- } +- .serialize() +-} +diff --git a/hdc_rust/src/utils.rs b/hdc_rust/src/utils.rs +index 8226c071..2cb6c99e 100644 +--- a/hdc_rust/src/utils.rs ++++ b/hdc_rust/src/utils.rs +@@ -152,7 +152,7 @@ pub mod hdc_log { + #[macro_export] + macro_rules! info { + ($($arg:tt)+) => { +- log::info!($($arg)+); ++ log::info!($($arg)+) + }; + } + +-- +Gitee + diff --git a/todo_list/session_manager/todo.md b/todo_list/session_manager/todo.md new file mode 100644 index 0000000000000000000000000000000000000000..c92406895f00b0570c4f0df15c26d9ab6b473839 --- /dev/null +++ b/todo_list/session_manager/todo.md @@ -0,0 +1,6 @@ +已完成: +1. session free机制 +2. channel free机制 + +待验证: +1. file send/recv 终止标记是否生效 \ No newline at end of file