1cc290419Sopenharmony_ci/* 2cc290419Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License. 5cc290419Sopenharmony_ci * You may obtain a copy of the License at 6cc290419Sopenharmony_ci * 7cc290419Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cc290419Sopenharmony_ci * 9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and 13cc290419Sopenharmony_ci * limitations under the License. 14cc290419Sopenharmony_ci */ 15cc290419Sopenharmony_ciuse crate::auth::{handshake_task, start_handshake_with_daemon}; 16cc290419Sopenharmony_ciuse crate::config::*; 17cc290419Sopenharmony_ciuse crate::host_app; 18cc290419Sopenharmony_ciuse crate::host_app::HostAppTaskMap; 19cc290419Sopenharmony_ciuse hdc::common::forward::{self, ForwardTaskMap, HdcForward}; 20cc290419Sopenharmony_ci/// ActionType 未定义,临时屏蔽 21cc290419Sopenharmony_ci/// use crate::host_app::HostAppTask; 22cc290419Sopenharmony_ci/// use hdc::common::hdcfile::HdcFile; 23cc290419Sopenharmony_ciuse hdc::common::hdcfile::{self, FileTaskMap, HdcFile}; 24cc290419Sopenharmony_ciuse hdc::config::{ConnectType, HdcCommand}; 25cc290419Sopenharmony_ciuse hdc::host_transfer::host_usb; 26cc290419Sopenharmony_ciuse hdc::transfer; 27cc290419Sopenharmony_ciuse hdc::transfer::send_channel_data; 28cc290419Sopenharmony_ciuse hdc::utils; 29cc290419Sopenharmony_ci#[allow(unused)] 30cc290419Sopenharmony_ciuse hdc::utils::hdc_log::*; 31cc290419Sopenharmony_ciuse std::collections::HashMap; 32cc290419Sopenharmony_ciuse std::io::{self, Error, ErrorKind}; 33cc290419Sopenharmony_ciuse std::sync::Arc; 34cc290419Sopenharmony_ci 35cc290419Sopenharmony_ci#[cfg(feature = "host")] 36cc290419Sopenharmony_ciextern crate ylong_runtime_static as ylong_runtime; 37cc290419Sopenharmony_ciuse ylong_runtime::net::SplitReadHalf; 38cc290419Sopenharmony_ciuse ylong_runtime::net::TcpStream; 39cc290419Sopenharmony_ciuse ylong_runtime::sync::{Mutex, RwLock, mpsc}; 40cc290419Sopenharmony_ci 41cc290419Sopenharmony_ciuse crate::host_app::HostAppTask; 42cc290419Sopenharmony_ci 43cc290419Sopenharmony_ci#[derive(Debug, Clone)] 44cc290419Sopenharmony_cipub struct TaskInfo { 45cc290419Sopenharmony_ci pub command: HdcCommand, 46cc290419Sopenharmony_ci pub connect_key: String, 47cc290419Sopenharmony_ci pub channel_id: u32, 48cc290419Sopenharmony_ci pub params: Vec<String>, 49cc290419Sopenharmony_ci} 50cc290419Sopenharmony_ci 51cc290419Sopenharmony_cipub async fn channel_task_dispatch(task_info: TaskInfo) -> io::Result<()> { 52cc290419Sopenharmony_ci hdc::debug!( 53cc290419Sopenharmony_ci "in channel_task_dispatch, task_info={:#?}", 54cc290419Sopenharmony_ci task_info.clone() 55cc290419Sopenharmony_ci ); 56cc290419Sopenharmony_ci 57cc290419Sopenharmony_ci match task_info.command { 58cc290419Sopenharmony_ci HdcCommand::UnityRunmode | HdcCommand::UnityRootrun => { 59cc290419Sopenharmony_ci hdc::trace!("dispatch to runmode task"); 60cc290419Sopenharmony_ci channel_unity_task(task_info).await? 61cc290419Sopenharmony_ci } 62cc290419Sopenharmony_ci HdcCommand::UnityReboot => { 63cc290419Sopenharmony_ci send_to_daemon(task_info, HdcCommand::UnityReboot, 0, true).await?; 64cc290419Sopenharmony_ci } 65cc290419Sopenharmony_ci | HdcCommand::UnityRemount => { 66cc290419Sopenharmony_ci send_to_daemon(task_info, HdcCommand::UnityRemount, 2, false).await?; 67cc290419Sopenharmony_ci } 68cc290419Sopenharmony_ci HdcCommand::UnityExecute | HdcCommand::ShellInit | HdcCommand::ShellData => { 69cc290419Sopenharmony_ci hdc::trace!("dispatch to shell task"); 70cc290419Sopenharmony_ci channel_shell_task(task_info).await? 71cc290419Sopenharmony_ci } 72cc290419Sopenharmony_ci HdcCommand::KernelTargetConnect => { 73cc290419Sopenharmony_ci hdc::trace!("dispatch to tconn task"); 74cc290419Sopenharmony_ci channel_connect_task(task_info).await?; 75cc290419Sopenharmony_ci } 76cc290419Sopenharmony_ci HdcCommand::KernelTargetList => { 77cc290419Sopenharmony_ci hdc::trace!("dispatch to list task"); 78cc290419Sopenharmony_ci channel_list_targets_task(task_info).await?; 79cc290419Sopenharmony_ci } 80cc290419Sopenharmony_ci HdcCommand::KernelWaitFor => { 81cc290419Sopenharmony_ci hdc::trace!("dispatch to wait"); 82cc290419Sopenharmony_ci channel_wait_for_any(task_info).await?; 83cc290419Sopenharmony_ci } 84cc290419Sopenharmony_ci HdcCommand::KernelChannelClose => { 85cc290419Sopenharmony_ci hdc::trace!("dispatch to close task"); 86cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 87cc290419Sopenharmony_ci } 88cc290419Sopenharmony_ci HdcCommand::FileInit 89cc290419Sopenharmony_ci | HdcCommand::FileBegin 90cc290419Sopenharmony_ci | HdcCommand::FileData 91cc290419Sopenharmony_ci | HdcCommand::FileCheck 92cc290419Sopenharmony_ci | HdcCommand::FileFinish 93cc290419Sopenharmony_ci | HdcCommand::AppInit 94cc290419Sopenharmony_ci | HdcCommand::AppBegin 95cc290419Sopenharmony_ci | HdcCommand::AppData 96cc290419Sopenharmony_ci | HdcCommand::AppFinish 97cc290419Sopenharmony_ci | HdcCommand::AppUninstall => { 98cc290419Sopenharmony_ci channel_file_task(task_info).await?; 99cc290419Sopenharmony_ci } 100cc290419Sopenharmony_ci HdcCommand::FileRecvInit => { 101cc290419Sopenharmony_ci send_to_daemon(task_info, HdcCommand::FileInit, 2, false).await?; 102cc290419Sopenharmony_ci } 103cc290419Sopenharmony_ci HdcCommand::UnityHilog => { 104cc290419Sopenharmony_ci channel_hilog_task(task_info).await?; 105cc290419Sopenharmony_ci } 106cc290419Sopenharmony_ci HdcCommand::UnityBugreportInit => { 107cc290419Sopenharmony_ci channel_bug_report_task(task_info).await?; 108cc290419Sopenharmony_ci } 109cc290419Sopenharmony_ci 110cc290419Sopenharmony_ci HdcCommand::ForwardInit => { 111cc290419Sopenharmony_ci channel_forward_task(task_info).await?; 112cc290419Sopenharmony_ci } 113cc290419Sopenharmony_ci HdcCommand::ForwardRportInit => { 114cc290419Sopenharmony_ci send_to_daemon(task_info, HdcCommand::ForwardInit, 1, false).await?; 115cc290419Sopenharmony_ci } 116cc290419Sopenharmony_ci HdcCommand::ForwardRportList => { 117cc290419Sopenharmony_ci channel_forward_list(task_info, false).await?; 118cc290419Sopenharmony_ci } 119cc290419Sopenharmony_ci HdcCommand::ForwardList => { 120cc290419Sopenharmony_ci channel_forward_list(task_info, true).await?; 121cc290419Sopenharmony_ci } 122cc290419Sopenharmony_ci HdcCommand::ForwardRemove => { 123cc290419Sopenharmony_ci channel_forward_remove(task_info, true).await?; 124cc290419Sopenharmony_ci } 125cc290419Sopenharmony_ci HdcCommand::ForwardRportRemove => { 126cc290419Sopenharmony_ci channel_forward_remove(task_info, false).await?; 127cc290419Sopenharmony_ci } 128cc290419Sopenharmony_ci HdcCommand::JdwpList | HdcCommand::JdwpTrack => { 129cc290419Sopenharmony_ci channel_jdwp_task(task_info).await?; 130cc290419Sopenharmony_ci } 131cc290419Sopenharmony_ci HdcCommand::KernelCheckServer => { 132cc290419Sopenharmony_ci check_server_task(task_info).await?; 133cc290419Sopenharmony_ci } 134cc290419Sopenharmony_ci _ => { 135cc290419Sopenharmony_ci hdc::info!("get unknown command {:#?}", task_info.command); 136cc290419Sopenharmony_ci return Err(Error::new(ErrorKind::Other, "command not found")); 137cc290419Sopenharmony_ci } 138cc290419Sopenharmony_ci } 139cc290419Sopenharmony_ci Ok(()) 140cc290419Sopenharmony_ci} 141cc290419Sopenharmony_ci 142cc290419Sopenharmony_ciasync fn channel_forward_task(task_info: TaskInfo) -> io::Result<()> { 143cc290419Sopenharmony_ci let session_id = 144cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 145cc290419Sopenharmony_ci let payload = task_info.params[1..].join(" ").into_bytes(); 146cc290419Sopenharmony_ci match task_info.command { 147cc290419Sopenharmony_ci HdcCommand::ForwardInit => { 148cc290419Sopenharmony_ci let mut task = HdcForward::new(session_id, task_info.channel_id, true); 149cc290419Sopenharmony_ci task.transfer.server_or_daemon = true; 150cc290419Sopenharmony_ci ForwardTaskMap::update(session_id, task_info.channel_id, task).await; 151cc290419Sopenharmony_ci forward::command_dispatch( 152cc290419Sopenharmony_ci session_id, 153cc290419Sopenharmony_ci task_info.channel_id, 154cc290419Sopenharmony_ci task_info.command, 155cc290419Sopenharmony_ci payload.as_slice(), 156cc290419Sopenharmony_ci payload.len() as u16, 157cc290419Sopenharmony_ci ) 158cc290419Sopenharmony_ci .await; 159cc290419Sopenharmony_ci return Ok(()); 160cc290419Sopenharmony_ci } 161cc290419Sopenharmony_ci _ => { 162cc290419Sopenharmony_ci hdc::warn!("channel_forward_task, other commands"); 163cc290419Sopenharmony_ci } 164cc290419Sopenharmony_ci } 165cc290419Sopenharmony_ci Ok(()) 166cc290419Sopenharmony_ci} 167cc290419Sopenharmony_ci 168cc290419Sopenharmony_ciasync fn channel_forward_remove(task_info: TaskInfo, forward_or_reverse: bool) -> io::Result<()> { 169cc290419Sopenharmony_ci let task_string = task_info.params[2..].join(" ").clone(); 170cc290419Sopenharmony_ci let session_id = 171cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 172cc290419Sopenharmony_ci hdc::info!( 173cc290419Sopenharmony_ci "channel_forward_remove task_string:{}, session_id:{}", 174cc290419Sopenharmony_ci task_string, 175cc290419Sopenharmony_ci session_id 176cc290419Sopenharmony_ci ); 177cc290419Sopenharmony_ci let _result = 178cc290419Sopenharmony_ci forward::HdcForwardInfoMap::remove_forward(task_string.clone(), forward_or_reverse).await; 179cc290419Sopenharmony_ci hdc::info!("channel_forward_remove remove result:{}", _result); 180cc290419Sopenharmony_ci if !_result { 181cc290419Sopenharmony_ci let message_str = format!("Remove forward ruler failed, ruler is not exist {}", task_string); 182cc290419Sopenharmony_ci let _ = transfer::send_channel_msg( 183cc290419Sopenharmony_ci task_info.channel_id, 184cc290419Sopenharmony_ci transfer::EchoLevel::FAIL, 185cc290419Sopenharmony_ci message_str, 186cc290419Sopenharmony_ci ) 187cc290419Sopenharmony_ci .await; 188cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 189cc290419Sopenharmony_ci return Ok(()); 190cc290419Sopenharmony_ci } 191cc290419Sopenharmony_ci let forward_channel_id = forward::ForwardTaskMap::get_channel_id(session_id, task_string.clone()).await; 192cc290419Sopenharmony_ci if let Some(_channel_id) = forward_channel_id { 193cc290419Sopenharmony_ci forward::free_channel_task(session_id, _channel_id).await; 194cc290419Sopenharmony_ci } 195cc290419Sopenharmony_ci let message_str = format!("Remove forward ruler success, ruler:{}", task_string); 196cc290419Sopenharmony_ci send_channel_data( 197cc290419Sopenharmony_ci task_info.channel_id, 198cc290419Sopenharmony_ci message_str.as_bytes().to_vec(), 199cc290419Sopenharmony_ci ) 200cc290419Sopenharmony_ci .await; 201cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 202cc290419Sopenharmony_ci Ok(()) 203cc290419Sopenharmony_ci} 204cc290419Sopenharmony_ci 205cc290419Sopenharmony_ciasync fn channel_forward_list(task_info: TaskInfo, forward_or_reverse: bool) -> io::Result<()> { 206cc290419Sopenharmony_ci let mut result = forward::HdcForwardInfoMap::get_all_forward_infos().await; 207cc290419Sopenharmony_ci if result.is_empty() { 208cc290419Sopenharmony_ci send_channel_data(task_info.channel_id, "[Empty]".as_bytes().to_vec()).await; 209cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 210cc290419Sopenharmony_ci return Ok(()); 211cc290419Sopenharmony_ci } 212cc290419Sopenharmony_ci for item in &mut result { 213cc290419Sopenharmony_ci let connect_key = ConnectMap::get_connect_key(item.session_id).await; 214cc290419Sopenharmony_ci if let Some(key) = connect_key { 215cc290419Sopenharmony_ci item.connect_key = key.clone(); 216cc290419Sopenharmony_ci } 217cc290419Sopenharmony_ci } 218cc290419Sopenharmony_ci 219cc290419Sopenharmony_ci let mut result_str = String::new(); 220cc290419Sopenharmony_ci for info in result { 221cc290419Sopenharmony_ci if info.forward_direction != forward_or_reverse { 222cc290419Sopenharmony_ci continue; 223cc290419Sopenharmony_ci } 224cc290419Sopenharmony_ci let task_string = info.task_string[2..].to_string(); 225cc290419Sopenharmony_ci let forward_str = if info.forward_direction { 226cc290419Sopenharmony_ci "[Forward]".to_string() 227cc290419Sopenharmony_ci } else { 228cc290419Sopenharmony_ci "[Reverse]".to_string() 229cc290419Sopenharmony_ci }; 230cc290419Sopenharmony_ci let line = format!( 231cc290419Sopenharmony_ci "{} {} {}\n", 232cc290419Sopenharmony_ci info.connect_key, task_string, forward_str 233cc290419Sopenharmony_ci ); 234cc290419Sopenharmony_ci result_str.push_str(&line); 235cc290419Sopenharmony_ci } 236cc290419Sopenharmony_ci send_channel_data(task_info.channel_id, result_str.as_bytes().to_vec()).await; 237cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 238cc290419Sopenharmony_ci Ok(()) 239cc290419Sopenharmony_ci} 240cc290419Sopenharmony_ci 241cc290419Sopenharmony_ciasync fn channel_jdwp_task(task_info: TaskInfo) -> io::Result<()> { 242cc290419Sopenharmony_ci let session_id = 243cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 244cc290419Sopenharmony_ci let mut payload = Vec::<u8>::new(); 245cc290419Sopenharmony_ci if task_info.params.len() >= 2 && task_info.params[1].starts_with('-') && task_info.params[1].len() >= 2 { 246cc290419Sopenharmony_ci payload = task_info.params[1][1..].as_bytes().to_vec(); 247cc290419Sopenharmony_ci } 248cc290419Sopenharmony_ci transfer::put( 249cc290419Sopenharmony_ci session_id, 250cc290419Sopenharmony_ci TaskMessage { 251cc290419Sopenharmony_ci channel_id: task_info.channel_id, 252cc290419Sopenharmony_ci command: task_info.command, 253cc290419Sopenharmony_ci payload, 254cc290419Sopenharmony_ci }, 255cc290419Sopenharmony_ci ) 256cc290419Sopenharmony_ci .await; 257cc290419Sopenharmony_ci Ok(()) 258cc290419Sopenharmony_ci} 259cc290419Sopenharmony_ci 260cc290419Sopenharmony_ciasync fn channel_hilog_task(task_info: TaskInfo) -> io::Result<()> { 261cc290419Sopenharmony_ci let session_id = 262cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 263cc290419Sopenharmony_ci let payload = if task_info.params.len() > 1 && task_info.params[1] == "-h" { 264cc290419Sopenharmony_ci vec![104] 265cc290419Sopenharmony_ci } else { 266cc290419Sopenharmony_ci vec![0] 267cc290419Sopenharmony_ci }; 268cc290419Sopenharmony_ci transfer::put( 269cc290419Sopenharmony_ci session_id, 270cc290419Sopenharmony_ci TaskMessage { 271cc290419Sopenharmony_ci channel_id: task_info.channel_id, 272cc290419Sopenharmony_ci command: HdcCommand::UnityHilog, 273cc290419Sopenharmony_ci payload, 274cc290419Sopenharmony_ci }, 275cc290419Sopenharmony_ci ) 276cc290419Sopenharmony_ci .await; 277cc290419Sopenharmony_ci Ok(()) 278cc290419Sopenharmony_ci} 279cc290419Sopenharmony_ci 280cc290419Sopenharmony_ciasync fn channel_bug_report_task(task_info: TaskInfo) -> io::Result<()> { 281cc290419Sopenharmony_ci let session_id = 282cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 283cc290419Sopenharmony_ci transfer::put( 284cc290419Sopenharmony_ci session_id, 285cc290419Sopenharmony_ci TaskMessage { 286cc290419Sopenharmony_ci channel_id: task_info.channel_id, 287cc290419Sopenharmony_ci command: HdcCommand::UnityBugreportInit, 288cc290419Sopenharmony_ci payload: vec![], 289cc290419Sopenharmony_ci }, 290cc290419Sopenharmony_ci ) 291cc290419Sopenharmony_ci .await; 292cc290419Sopenharmony_ci Ok(()) 293cc290419Sopenharmony_ci} 294cc290419Sopenharmony_ci 295cc290419Sopenharmony_ciasync fn channel_file_task(task_info: TaskInfo) -> io::Result<()> { 296cc290419Sopenharmony_ci let session_id = 297cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 298cc290419Sopenharmony_ci let payload = task_info.params.join(" ").into_bytes(); 299cc290419Sopenharmony_ci match task_info.command { 300cc290419Sopenharmony_ci HdcCommand::AppInit | HdcCommand::AppUninstall => { 301cc290419Sopenharmony_ci match HostAppTaskMap::exist(session_id, task_info.channel_id).await { 302cc290419Sopenharmony_ci Ok(true) => {} 303cc290419Sopenharmony_ci Ok(false) => { 304cc290419Sopenharmony_ci HostAppTaskMap::put( 305cc290419Sopenharmony_ci session_id, 306cc290419Sopenharmony_ci task_info.channel_id, 307cc290419Sopenharmony_ci HostAppTask::new(session_id, task_info.channel_id), 308cc290419Sopenharmony_ci ) 309cc290419Sopenharmony_ci .await; 310cc290419Sopenharmony_ci } 311cc290419Sopenharmony_ci Err(err) => { 312cc290419Sopenharmony_ci return Err(io::Error::new( 313cc290419Sopenharmony_ci io::ErrorKind::Other, 314cc290419Sopenharmony_ci format!("call HostAppTaskMap::exist failed, {err:?}"), 315cc290419Sopenharmony_ci )); 316cc290419Sopenharmony_ci } 317cc290419Sopenharmony_ci } 318cc290419Sopenharmony_ci let _ = host_app::command_dispatch(session_id, task_info.channel_id, task_info.command, &payload) .await; 319cc290419Sopenharmony_ci } 320cc290419Sopenharmony_ci 321cc290419Sopenharmony_ci HdcCommand::FileCheck | HdcCommand::FileInit => { 322cc290419Sopenharmony_ci if !FileTaskMap::exsit(session_id, task_info.channel_id).await { 323cc290419Sopenharmony_ci let mut task = HdcFile::new(session_id, task_info.channel_id); 324cc290419Sopenharmony_ci task.transfer.server_or_daemon = true; 325cc290419Sopenharmony_ci FileTaskMap::put(session_id, task_info.channel_id, task).await; 326cc290419Sopenharmony_ci } 327cc290419Sopenharmony_ci hdcfile::command_dispatch( 328cc290419Sopenharmony_ci session_id, 329cc290419Sopenharmony_ci task_info.channel_id, 330cc290419Sopenharmony_ci task_info.command, 331cc290419Sopenharmony_ci &payload, 332cc290419Sopenharmony_ci payload.len() as u16, 333cc290419Sopenharmony_ci ) 334cc290419Sopenharmony_ci .await; 335cc290419Sopenharmony_ci return Ok(()); 336cc290419Sopenharmony_ci } 337cc290419Sopenharmony_ci HdcCommand::FileBegin | HdcCommand::FileData | HdcCommand::FileFinish => { 338cc290419Sopenharmony_ci hdcfile::command_dispatch( 339cc290419Sopenharmony_ci session_id, 340cc290419Sopenharmony_ci task_info.channel_id, 341cc290419Sopenharmony_ci task_info.command, 342cc290419Sopenharmony_ci &payload, 343cc290419Sopenharmony_ci payload.len() as u16, 344cc290419Sopenharmony_ci ) 345cc290419Sopenharmony_ci .await; 346cc290419Sopenharmony_ci return Ok(()); 347cc290419Sopenharmony_ci } 348cc290419Sopenharmony_ci _ => { 349cc290419Sopenharmony_ci hdc::info!("other tasks, payload is {:#?}", payload); 350cc290419Sopenharmony_ci } 351cc290419Sopenharmony_ci } 352cc290419Sopenharmony_ci Ok(()) 353cc290419Sopenharmony_ci} 354cc290419Sopenharmony_ci 355cc290419Sopenharmony_ciasync fn send_to_daemon(task_info: TaskInfo, _cmd: HdcCommand, param_start_idx: usize, async_flag: bool) -> io::Result<()> { 356cc290419Sopenharmony_ci let session_id = 357cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 358cc290419Sopenharmony_ci hdc::info!("task_info params is {:?}", task_info); 359cc290419Sopenharmony_ci transfer::put( 360cc290419Sopenharmony_ci session_id, 361cc290419Sopenharmony_ci TaskMessage { 362cc290419Sopenharmony_ci channel_id: task_info.channel_id, 363cc290419Sopenharmony_ci command: _cmd, 364cc290419Sopenharmony_ci payload: task_info.params[param_start_idx..].join(" ").into_bytes(), 365cc290419Sopenharmony_ci }, 366cc290419Sopenharmony_ci ) 367cc290419Sopenharmony_ci .await; 368cc290419Sopenharmony_ci if async_flag { 369cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 370cc290419Sopenharmony_ci } 371cc290419Sopenharmony_ci Ok(()) 372cc290419Sopenharmony_ci} 373cc290419Sopenharmony_ci 374cc290419Sopenharmony_ciasync fn channel_unity_task(task_info: TaskInfo) -> io::Result<()> { 375cc290419Sopenharmony_ci let session_id = match ConnectMap::get_session_id(task_info.connect_key.clone()).await { 376cc290419Sopenharmony_ci Some(seid) => seid, 377cc290419Sopenharmony_ci None => return Err(Error::new(ErrorKind::Other, "session not found")), 378cc290419Sopenharmony_ci }; 379cc290419Sopenharmony_ci let cmd = task_info.params[1..] 380cc290419Sopenharmony_ci .iter() 381cc290419Sopenharmony_ci .map(|s| s.trim_end_matches('\0')) 382cc290419Sopenharmony_ci .collect::<Vec<_>>() 383cc290419Sopenharmony_ci .join(" ") 384cc290419Sopenharmony_ci .into_bytes(); 385cc290419Sopenharmony_ci transfer::put( 386cc290419Sopenharmony_ci session_id, 387cc290419Sopenharmony_ci TaskMessage { 388cc290419Sopenharmony_ci channel_id: task_info.channel_id, 389cc290419Sopenharmony_ci command: task_info.command, 390cc290419Sopenharmony_ci payload: cmd, 391cc290419Sopenharmony_ci }, 392cc290419Sopenharmony_ci ) 393cc290419Sopenharmony_ci .await; 394cc290419Sopenharmony_ci Ok(()) 395cc290419Sopenharmony_ci} 396cc290419Sopenharmony_ci 397cc290419Sopenharmony_ciasync fn channel_shell_task(task_info: TaskInfo) -> io::Result<()> { 398cc290419Sopenharmony_ci let session_id = 399cc290419Sopenharmony_ci get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?; 400cc290419Sopenharmony_ci match task_info.command { 401cc290419Sopenharmony_ci HdcCommand::UnityExecute => { 402cc290419Sopenharmony_ci let cmd = task_info.params[1..] 403cc290419Sopenharmony_ci .iter() 404cc290419Sopenharmony_ci .map(|s| s.trim_end_matches('\0')) 405cc290419Sopenharmony_ci .collect::<Vec<_>>() 406cc290419Sopenharmony_ci .join(" ") 407cc290419Sopenharmony_ci .into_bytes(); 408cc290419Sopenharmony_ci transfer::put( 409cc290419Sopenharmony_ci session_id, 410cc290419Sopenharmony_ci TaskMessage { 411cc290419Sopenharmony_ci channel_id: task_info.channel_id, 412cc290419Sopenharmony_ci command: task_info.command, 413cc290419Sopenharmony_ci payload: cmd, 414cc290419Sopenharmony_ci }, 415cc290419Sopenharmony_ci ) 416cc290419Sopenharmony_ci .await; 417cc290419Sopenharmony_ci } 418cc290419Sopenharmony_ci HdcCommand::ShellInit => { 419cc290419Sopenharmony_ci transfer::put( 420cc290419Sopenharmony_ci session_id, 421cc290419Sopenharmony_ci TaskMessage { 422cc290419Sopenharmony_ci channel_id: task_info.channel_id, 423cc290419Sopenharmony_ci command: task_info.command, 424cc290419Sopenharmony_ci payload: vec![0], 425cc290419Sopenharmony_ci }, 426cc290419Sopenharmony_ci ) 427cc290419Sopenharmony_ci .await; 428cc290419Sopenharmony_ci } 429cc290419Sopenharmony_ci HdcCommand::ShellData => { 430cc290419Sopenharmony_ci let payload = task_info.params.join("").into_bytes(); 431cc290419Sopenharmony_ci transfer::put( 432cc290419Sopenharmony_ci session_id, 433cc290419Sopenharmony_ci TaskMessage { 434cc290419Sopenharmony_ci channel_id: task_info.channel_id, 435cc290419Sopenharmony_ci command: task_info.command, 436cc290419Sopenharmony_ci payload, 437cc290419Sopenharmony_ci }, 438cc290419Sopenharmony_ci ) 439cc290419Sopenharmony_ci .await; 440cc290419Sopenharmony_ci } 441cc290419Sopenharmony_ci _ => {} 442cc290419Sopenharmony_ci } 443cc290419Sopenharmony_ci 444cc290419Sopenharmony_ci Ok(()) 445cc290419Sopenharmony_ci} 446cc290419Sopenharmony_ci 447cc290419Sopenharmony_ciasync fn channel_connect_task(task_info: TaskInfo) -> io::Result<()> { 448cc290419Sopenharmony_ci let connect_key = task_info.params[1].trim_end_matches('\0').to_string(); 449cc290419Sopenharmony_ci if ConnectMap::get(connect_key.clone()).await.is_some() { 450cc290419Sopenharmony_ci let ret = transfer::send_channel_msg( 451cc290419Sopenharmony_ci task_info.channel_id, 452cc290419Sopenharmony_ci transfer::EchoLevel::INFO, 453cc290419Sopenharmony_ci "Target is connected, repeat operation".to_string(), 454cc290419Sopenharmony_ci ) 455cc290419Sopenharmony_ci .await; 456cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 457cc290419Sopenharmony_ci return ret; 458cc290419Sopenharmony_ci } 459cc290419Sopenharmony_ci start_tcp_daemon_session(connect_key, &task_info).await 460cc290419Sopenharmony_ci} 461cc290419Sopenharmony_ci 462cc290419Sopenharmony_cipub async fn usb_handle_deamon(ptr: u64, mut rx: mpsc::BoundedReceiver<(TaskMessage, u32)>, session_id: u32, connect_key: String) -> io::Result<()> { 463cc290419Sopenharmony_ci loop { 464cc290419Sopenharmony_ci match rx.recv().await { 465cc290419Sopenharmony_ci Ok((task_message, _index)) => { 466cc290419Sopenharmony_ci hdc::debug!( 467cc290419Sopenharmony_ci "in usb_handle_deamon, recv cmd: {:#?}, payload len: {}", 468cc290419Sopenharmony_ci task_message.command, 469cc290419Sopenharmony_ci task_message.payload.len(), 470cc290419Sopenharmony_ci ); 471cc290419Sopenharmony_ci if let Err(e) = session_task_dispatch(task_message, session_id, connect_key.clone()).await { 472cc290419Sopenharmony_ci hdc::error!("dispatch task failed: {}", e.to_string()); 473cc290419Sopenharmony_ci } 474cc290419Sopenharmony_ci } 475cc290419Sopenharmony_ci Err(e) => { 476cc290419Sopenharmony_ci hdc::warn!("unpack task failed: {}", e.to_string()); 477cc290419Sopenharmony_ci ConnectMap::remove(connect_key.clone()).await; 478cc290419Sopenharmony_ci host_usb::on_device_connected(ptr, connect_key, false); 479cc290419Sopenharmony_ci return Err(Error::new(ErrorKind::Other, "recv error")); 480cc290419Sopenharmony_ci } 481cc290419Sopenharmony_ci }; 482cc290419Sopenharmony_ci } 483cc290419Sopenharmony_ci} 484cc290419Sopenharmony_ci 485cc290419Sopenharmony_cipub async fn start_usb_device_loop(ptr: u64, connect_key: String) { 486cc290419Sopenharmony_ci let session_id = utils::get_pseudo_random_u32(); 487cc290419Sopenharmony_ci let wr = host_usb::HostUsbWriter { 488cc290419Sopenharmony_ci connect_key: connect_key.clone(), 489cc290419Sopenharmony_ci ptr, 490cc290419Sopenharmony_ci }; 491cc290419Sopenharmony_ci host_usb::HostUsbMap::start(session_id, wr).await; 492cc290419Sopenharmony_ci let rx = host_usb::start_recv(ptr, connect_key.clone(), session_id); 493cc290419Sopenharmony_ci let channel_id = utils::get_pseudo_random_u32(); 494cc290419Sopenharmony_ci hdc::info!("generate new session {} channel {}", session_id, channel_id); 495cc290419Sopenharmony_ci start_handshake_with_daemon(connect_key.clone(), session_id, channel_id, ConnectType::HostUsb(connect_key.clone())).await; 496cc290419Sopenharmony_ci let _ = ylong_runtime::spawn(usb_handle_deamon(ptr, rx, session_id, connect_key)).await; 497cc290419Sopenharmony_ci} 498cc290419Sopenharmony_ci 499cc290419Sopenharmony_ciasync fn start_tcp_daemon_session(connect_key: String, task_info: &TaskInfo) -> io::Result<()> { 500cc290419Sopenharmony_ci match TcpStream::connect(connect_key.clone()).await { 501cc290419Sopenharmony_ci Err(_) => { 502cc290419Sopenharmony_ci let ret = transfer::send_channel_msg( 503cc290419Sopenharmony_ci task_info.channel_id, 504cc290419Sopenharmony_ci transfer::EchoLevel::FAIL, 505cc290419Sopenharmony_ci "Connect to daemon failed".to_string(), 506cc290419Sopenharmony_ci ) 507cc290419Sopenharmony_ci .await; 508cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 509cc290419Sopenharmony_ci ret 510cc290419Sopenharmony_ci } 511cc290419Sopenharmony_ci Ok(stream) => { 512cc290419Sopenharmony_ci let session_id = utils::get_pseudo_random_u32(); 513cc290419Sopenharmony_ci let (rd, wr) = stream.into_split(); 514cc290419Sopenharmony_ci transfer::TcpMap::start(session_id, wr).await; 515cc290419Sopenharmony_ci 516cc290419Sopenharmony_ci start_handshake_with_daemon(connect_key.clone(), session_id, task_info.channel_id, ConnectType::Tcp).await; 517cc290419Sopenharmony_ci ylong_runtime::spawn(tcp_handle_deamon(rd, session_id, connect_key)); 518cc290419Sopenharmony_ci transfer::send_channel_msg( 519cc290419Sopenharmony_ci task_info.channel_id, 520cc290419Sopenharmony_ci transfer::EchoLevel::INFO, 521cc290419Sopenharmony_ci "Connect OK".to_string(), 522cc290419Sopenharmony_ci ) 523cc290419Sopenharmony_ci .await?; 524cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 525cc290419Sopenharmony_ci Ok(()) 526cc290419Sopenharmony_ci } 527cc290419Sopenharmony_ci } 528cc290419Sopenharmony_ci} 529cc290419Sopenharmony_ci 530cc290419Sopenharmony_ciasync fn channel_list_targets_task(task_info: TaskInfo) -> io::Result<()> { 531cc290419Sopenharmony_ci let is_full = task_info.params.contains(&"-v".to_string()); 532cc290419Sopenharmony_ci let target_list = ConnectMap::get_list(is_full).await; 533cc290419Sopenharmony_ci let msg = if target_list.is_empty() { 534cc290419Sopenharmony_ci "[Empty]".to_string() 535cc290419Sopenharmony_ci } else { 536cc290419Sopenharmony_ci target_list.join("\n") 537cc290419Sopenharmony_ci }; 538cc290419Sopenharmony_ci transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; 539cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 540cc290419Sopenharmony_ci Ok(()) 541cc290419Sopenharmony_ci} 542cc290419Sopenharmony_ci 543cc290419Sopenharmony_ci// check if any daemon connected and send the message to client for wait 544cc290419Sopenharmony_ciasync fn channel_wait_for_any(task_info: TaskInfo) -> io::Result<()> { 545cc290419Sopenharmony_ci let target_list = ConnectMap::get_list(false).await; 546cc290419Sopenharmony_ci if target_list.is_empty() { 547cc290419Sopenharmony_ci hdc::info!("No any connected target"); 548cc290419Sopenharmony_ci let msg = "No connected target".to_string(); 549cc290419Sopenharmony_ci transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; 550cc290419Sopenharmony_ci } else if task_info.connect_key == "any" { 551cc290419Sopenharmony_ci hdc::info!("Wait for connected target any"); 552cc290419Sopenharmony_ci let msg = "Wait for connected target any get ".to_string() + target_list[0].as_str(); 553cc290419Sopenharmony_ci transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; 554cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 555cc290419Sopenharmony_ci } else { 556cc290419Sopenharmony_ci // wait for special connectkey 557cc290419Sopenharmony_ci if target_list 558cc290419Sopenharmony_ci .iter() 559cc290419Sopenharmony_ci .any(|connect_key| connect_key == &task_info.connect_key) 560cc290419Sopenharmony_ci { 561cc290419Sopenharmony_ci hdc::info!("Wait for connected target is {}", task_info.connect_key); 562cc290419Sopenharmony_ci let msg = "Wait for connected target is ".to_string() + task_info.connect_key.as_str(); 563cc290419Sopenharmony_ci transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; 564cc290419Sopenharmony_ci transfer::TcpMap::end(task_info.channel_id).await; 565cc290419Sopenharmony_ci } else { 566cc290419Sopenharmony_ci hdc::info!("No {} connected target ", task_info.connect_key); 567cc290419Sopenharmony_ci let msg = "No connected target".to_string(); 568cc290419Sopenharmony_ci transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?; 569cc290419Sopenharmony_ci } 570cc290419Sopenharmony_ci } 571cc290419Sopenharmony_ci Ok(()) 572cc290419Sopenharmony_ci} 573cc290419Sopenharmony_ci 574cc290419Sopenharmony_ciasync fn tcp_handle_deamon( 575cc290419Sopenharmony_ci mut rd: SplitReadHalf, 576cc290419Sopenharmony_ci session_id: u32, 577cc290419Sopenharmony_ci connect_key: String, 578cc290419Sopenharmony_ci) -> io::Result<()> { 579cc290419Sopenharmony_ci loop { 580cc290419Sopenharmony_ci match transfer::tcp::unpack_task_message(&mut rd).await { 581cc290419Sopenharmony_ci Ok(task_message) => { 582cc290419Sopenharmony_ci // hdc::info!( 583cc290419Sopenharmony_ci // "in tcp_handle_deamon, recv cmd: {:#?}, payload len: {}", 584cc290419Sopenharmony_ci // task_message.command, 585cc290419Sopenharmony_ci // task_message.payload.len(), 586cc290419Sopenharmony_ci // ); 587cc290419Sopenharmony_ci if let Err(e) = session_task_dispatch(task_message, session_id, connect_key.clone()).await { 588cc290419Sopenharmony_ci hdc::error!("dispatch task failed: {}", e.to_string()); 589cc290419Sopenharmony_ci } 590cc290419Sopenharmony_ci } 591cc290419Sopenharmony_ci Err(e) => { 592cc290419Sopenharmony_ci hdc::warn!("unpack task failed: {}", e.to_string()); 593cc290419Sopenharmony_ci ConnectMap::remove(connect_key).await; 594cc290419Sopenharmony_ci return Err(e); 595cc290419Sopenharmony_ci } 596cc290419Sopenharmony_ci }; 597cc290419Sopenharmony_ci } 598cc290419Sopenharmony_ci} 599cc290419Sopenharmony_ci 600cc290419Sopenharmony_ciasync fn session_task_dispatch(task_message: TaskMessage, session_id: u32, connect_key: String) -> io::Result<()> { 601cc290419Sopenharmony_ci match task_message.command { 602cc290419Sopenharmony_ci HdcCommand::KernelEcho => { 603cc290419Sopenharmony_ci let data = task_message.payload[1..].to_vec(); 604cc290419Sopenharmony_ci let level_result = transfer::EchoLevel::convert_from_message_level(task_message.payload[0]); 605cc290419Sopenharmony_ci match level_result { 606cc290419Sopenharmony_ci Ok(level) => { 607cc290419Sopenharmony_ci if let Ok(str) = String::from_utf8(data) { 608cc290419Sopenharmony_ci if let Err(e) = transfer::send_channel_msg( 609cc290419Sopenharmony_ci task_message.channel_id, 610cc290419Sopenharmony_ci level, 611cc290419Sopenharmony_ci str, 612cc290419Sopenharmony_ci ).await { 613cc290419Sopenharmony_ci hdc::error!("echo to client failed: {}", e.to_string()); 614cc290419Sopenharmony_ci }; 615cc290419Sopenharmony_ci } 616cc290419Sopenharmony_ci } 617cc290419Sopenharmony_ci Err(_) => { 618cc290419Sopenharmony_ci return Err(Error::new(ErrorKind::Other, "message level invalid.")); 619cc290419Sopenharmony_ci } 620cc290419Sopenharmony_ci } 621cc290419Sopenharmony_ci } 622cc290419Sopenharmony_ci HdcCommand::KernelEchoRaw | HdcCommand::UnityBugreportData => { 623cc290419Sopenharmony_ci transfer::send_channel_data(task_message.channel_id, task_message.payload).await; 624cc290419Sopenharmony_ci } 625cc290419Sopenharmony_ci HdcCommand::KernelChannelClose => { 626cc290419Sopenharmony_ci session_channel_close(task_message, session_id).await?; 627cc290419Sopenharmony_ci } 628cc290419Sopenharmony_ci HdcCommand::KernelHandshake => { 629cc290419Sopenharmony_ci handshake_task(task_message, session_id, connect_key).await?; 630cc290419Sopenharmony_ci } 631cc290419Sopenharmony_ci HdcCommand::AppBegin 632cc290419Sopenharmony_ci | HdcCommand::AppData 633cc290419Sopenharmony_ci | HdcCommand::AppFinish 634cc290419Sopenharmony_ci | HdcCommand::FileInit 635cc290419Sopenharmony_ci | HdcCommand::FileBegin 636cc290419Sopenharmony_ci | HdcCommand::FileData 637cc290419Sopenharmony_ci | HdcCommand::FileCheck 638cc290419Sopenharmony_ci | HdcCommand::FileFinish => { 639cc290419Sopenharmony_ci session_file_task(task_message, session_id).await?; 640cc290419Sopenharmony_ci } 641cc290419Sopenharmony_ci HdcCommand::ForwardCheck 642cc290419Sopenharmony_ci | HdcCommand::ForwardActiveMaster 643cc290419Sopenharmony_ci | HdcCommand::ForwardActiveSlave 644cc290419Sopenharmony_ci | HdcCommand::ForwardCheckResult 645cc290419Sopenharmony_ci | HdcCommand::ForwardData => { 646cc290419Sopenharmony_ci if HdcCommand::ForwardCheck == task_message.command { 647cc290419Sopenharmony_ci let mut task = HdcForward::new(session_id, task_message.channel_id, true); 648cc290419Sopenharmony_ci task.transfer.server_or_daemon = true; 649cc290419Sopenharmony_ci ForwardTaskMap::update(session_id, task_message.channel_id, task).await; 650cc290419Sopenharmony_ci } 651cc290419Sopenharmony_ci session_forward_task(task_message, session_id).await?; 652cc290419Sopenharmony_ci } 653cc290419Sopenharmony_ci HdcCommand::ForwardSuccess => { 654cc290419Sopenharmony_ci session_forward_success(task_message, session_id).await?; 655cc290419Sopenharmony_ci } 656cc290419Sopenharmony_ci _ => {} 657cc290419Sopenharmony_ci } 658cc290419Sopenharmony_ci Ok(()) 659cc290419Sopenharmony_ci} 660cc290419Sopenharmony_ci 661cc290419Sopenharmony_ciasync fn session_forward_task(task_message: TaskMessage, session_id: u32) -> io::Result<()> { 662cc290419Sopenharmony_ci forward::command_dispatch( 663cc290419Sopenharmony_ci session_id, 664cc290419Sopenharmony_ci task_message.channel_id, 665cc290419Sopenharmony_ci task_message.command, 666cc290419Sopenharmony_ci &task_message.payload, 667cc290419Sopenharmony_ci task_message.payload.len() as u16, 668cc290419Sopenharmony_ci ) 669cc290419Sopenharmony_ci .await; 670cc290419Sopenharmony_ci Ok(()) 671cc290419Sopenharmony_ci} 672cc290419Sopenharmony_ci 673cc290419Sopenharmony_ciasync fn session_forward_success(task_message: TaskMessage, session_id: u32) -> io::Result<()> { 674cc290419Sopenharmony_ci let _ = forward::on_forward_success(task_message.clone(), session_id).await; 675cc290419Sopenharmony_ci Ok(()) 676cc290419Sopenharmony_ci} 677cc290419Sopenharmony_ci 678cc290419Sopenharmony_ciasync fn session_file_task(task_message: TaskMessage, session_id: u32) -> io::Result<()> { 679cc290419Sopenharmony_ci match task_message.command { 680cc290419Sopenharmony_ci HdcCommand::AppBegin | HdcCommand::AppFinish => { 681cc290419Sopenharmony_ci let _ = host_app::command_dispatch( 682cc290419Sopenharmony_ci session_id, 683cc290419Sopenharmony_ci task_message.channel_id, 684cc290419Sopenharmony_ci task_message.command, 685cc290419Sopenharmony_ci &task_message.payload, 686cc290419Sopenharmony_ci ) 687cc290419Sopenharmony_ci .await; 688cc290419Sopenharmony_ci return Ok(()); 689cc290419Sopenharmony_ci } 690cc290419Sopenharmony_ci HdcCommand::FileCheck | HdcCommand::FileInit => { 691cc290419Sopenharmony_ci if !FileTaskMap::exsit(session_id, task_message.channel_id).await { 692cc290419Sopenharmony_ci let mut task = HdcFile::new(session_id, task_message.channel_id); 693cc290419Sopenharmony_ci task.transfer.server_or_daemon = true; 694cc290419Sopenharmony_ci FileTaskMap::put(session_id, task_message.channel_id, task).await; 695cc290419Sopenharmony_ci } 696cc290419Sopenharmony_ci 697cc290419Sopenharmony_ci hdcfile::command_dispatch( 698cc290419Sopenharmony_ci session_id, 699cc290419Sopenharmony_ci task_message.channel_id, 700cc290419Sopenharmony_ci task_message.command, 701cc290419Sopenharmony_ci &task_message.payload, 702cc290419Sopenharmony_ci task_message.payload.len() as u16, 703cc290419Sopenharmony_ci ) 704cc290419Sopenharmony_ci .await; 705cc290419Sopenharmony_ci return Ok(()); 706cc290419Sopenharmony_ci } 707cc290419Sopenharmony_ci HdcCommand::FileBegin | HdcCommand::FileData | HdcCommand::FileFinish => { 708cc290419Sopenharmony_ci hdcfile::command_dispatch( 709cc290419Sopenharmony_ci session_id, 710cc290419Sopenharmony_ci task_message.channel_id, 711cc290419Sopenharmony_ci task_message.command, 712cc290419Sopenharmony_ci &task_message.payload, 713cc290419Sopenharmony_ci task_message.payload.len() as u16, 714cc290419Sopenharmony_ci ) 715cc290419Sopenharmony_ci .await; 716cc290419Sopenharmony_ci return Ok(()); 717cc290419Sopenharmony_ci } 718cc290419Sopenharmony_ci _ => { 719cc290419Sopenharmony_ci hdc::info!("other tasks"); 720cc290419Sopenharmony_ci } 721cc290419Sopenharmony_ci } 722cc290419Sopenharmony_ci /* ActionType 未定义,临时屏蔽 723cc290419Sopenharmony_ci let channel_id = task_message.channel_id; 724cc290419Sopenharmony_ci let command = task_message.command; 725cc290419Sopenharmony_ci 726cc290419Sopenharmony_ci let opt = admin_session(ActionType::Query(session_id)).await; 727cc290419Sopenharmony_ci if opt.is_none() { 728cc290419Sopenharmony_ci admin_session(ActionType::Add(HdcSession::new( 729cc290419Sopenharmony_ci session_id, 730cc290419Sopenharmony_ci String::from(""), 731cc290419Sopenharmony_ci NodeType::Server, 732cc290419Sopenharmony_ci ConnectType::Tcp, 733cc290419Sopenharmony_ci ))) 734cc290419Sopenharmony_ci .await; 735cc290419Sopenharmony_ci } 736cc290419Sopenharmony_ci let opt = admin_session(ActionType::Query(session_id)).await; 737cc290419Sopenharmony_ci 738cc290419Sopenharmony_ci let arc = opt.unwrap(); 739cc290419Sopenharmony_ci let mut session = arc.lock().await; 740cc290419Sopenharmony_ci if let std::collections::hash_map::Entry::Vacant(e) = session.map_tasks.entry(channel_id) { 741cc290419Sopenharmony_ci match command { 742cc290419Sopenharmony_ci HdcCommand::AppBegin => { 743cc290419Sopenharmony_ci let mut task = HostAppTask::new(session_id, channel_id); 744cc290419Sopenharmony_ci task.transfer.server_or_daemon = true; 745cc290419Sopenharmony_ci e.insert(Arc::new(Mutex::new(task))); 746cc290419Sopenharmony_ci } 747cc290419Sopenharmony_ci HdcCommand::FileInit => { 748cc290419Sopenharmony_ci let mut task = HdcFile::new(session_id, channel_id); 749cc290419Sopenharmony_ci task.transfer.server_or_daemon = true; 750cc290419Sopenharmony_ci e.insert(Arc::new(Mutex::new(task))); 751cc290419Sopenharmony_ci } 752cc290419Sopenharmony_ci _ => { 753cc290419Sopenharmony_ci hdc::info!("other tasks"); 754cc290419Sopenharmony_ci } 755cc290419Sopenharmony_ci } 756cc290419Sopenharmony_ci } 757cc290419Sopenharmony_ci let task = session.map_tasks.get(&channel_id).unwrap(); 758cc290419Sopenharmony_ci let task_ = &mut task.lock().await; 759cc290419Sopenharmony_ci let cmd = task_message.payload; 760cc290419Sopenharmony_ci let _ = task_.command_dispatch(command, &cmd[..], cmd.len() as u16); 761cc290419Sopenharmony_ci */ 762cc290419Sopenharmony_ci Ok(()) 763cc290419Sopenharmony_ci} 764cc290419Sopenharmony_ci 765cc290419Sopenharmony_cipub async fn session_channel_close(task_message: TaskMessage, session_id: u32) -> io::Result<()> { 766cc290419Sopenharmony_ci if task_message.payload[0] > 0 { 767cc290419Sopenharmony_ci let message = TaskMessage { 768cc290419Sopenharmony_ci channel_id: task_message.channel_id, 769cc290419Sopenharmony_ci command: HdcCommand::KernelChannelClose, 770cc290419Sopenharmony_ci payload: vec![task_message.payload[0] - 1], 771cc290419Sopenharmony_ci }; 772cc290419Sopenharmony_ci transfer::put(session_id, message).await; 773cc290419Sopenharmony_ci } 774cc290419Sopenharmony_ci hdc::info!("recv channel close {}", task_message.channel_id); 775cc290419Sopenharmony_ci transfer::TcpMap::end(task_message.channel_id).await; 776cc290419Sopenharmony_ci Ok(()) 777cc290419Sopenharmony_ci} 778cc290419Sopenharmony_ci 779cc290419Sopenharmony_ciasync fn check_server_task(task_info: TaskInfo) -> io::Result<()> { 780cc290419Sopenharmony_ci let payload = [ 781cc290419Sopenharmony_ci u16::to_le_bytes(HdcCommand::KernelCheckServer as u16).as_slice(), 782cc290419Sopenharmony_ci get_version().as_bytes(), 783cc290419Sopenharmony_ci ] 784cc290419Sopenharmony_ci .concat(); 785cc290419Sopenharmony_ci transfer::send_channel_data(task_info.channel_id, payload).await; 786cc290419Sopenharmony_ci Ok(()) 787cc290419Sopenharmony_ci} 788cc290419Sopenharmony_ci 789cc290419Sopenharmony_ci#[allow(unused)] 790cc290419Sopenharmony_ci#[derive(Default)] 791cc290419Sopenharmony_cipub enum ConnectStatus { 792cc290419Sopenharmony_ci #[default] 793cc290419Sopenharmony_ci Unknown = 0, 794cc290419Sopenharmony_ci Ready, 795cc290419Sopenharmony_ci Connected, 796cc290419Sopenharmony_ci Offline, 797cc290419Sopenharmony_ci} 798cc290419Sopenharmony_ci 799cc290419Sopenharmony_ci#[allow(unused)] 800cc290419Sopenharmony_ci#[derive(Default)] 801cc290419Sopenharmony_cipub struct DaemonInfo { 802cc290419Sopenharmony_ci pub session_id: u32, 803cc290419Sopenharmony_ci pub conn_type: ConnectType, 804cc290419Sopenharmony_ci pub conn_status: ConnectStatus, 805cc290419Sopenharmony_ci pub dev_name: String, 806cc290419Sopenharmony_ci pub version: String, 807cc290419Sopenharmony_ci pub emg_msg: String, 808cc290419Sopenharmony_ci pub daemon_auth_status: String, 809cc290419Sopenharmony_ci} 810cc290419Sopenharmony_ci 811cc290419Sopenharmony_citype DaemonInfo_ = Arc<Mutex<DaemonInfo>>; 812cc290419Sopenharmony_citype ConnectMap_ = Arc<RwLock<HashMap<String, DaemonInfo_>>>; 813cc290419Sopenharmony_ci 814cc290419Sopenharmony_cipub struct ConnectMap {} 815cc290419Sopenharmony_ciimpl ConnectMap { 816cc290419Sopenharmony_ci fn get_instance() -> ConnectMap_ { 817cc290419Sopenharmony_ci static mut CONNECT_TYPE_MAP: Option<ConnectMap_> = None; 818cc290419Sopenharmony_ci unsafe { 819cc290419Sopenharmony_ci CONNECT_TYPE_MAP 820cc290419Sopenharmony_ci .get_or_insert_with(|| Arc::new(RwLock::new(HashMap::new()))) 821cc290419Sopenharmony_ci .clone() 822cc290419Sopenharmony_ci } 823cc290419Sopenharmony_ci } 824cc290419Sopenharmony_ci 825cc290419Sopenharmony_ci async fn remove(connect_key: String) { 826cc290419Sopenharmony_ci let instance = Self::get_instance(); 827cc290419Sopenharmony_ci let mut map = instance.write().await; 828cc290419Sopenharmony_ci map.remove(&connect_key); 829cc290419Sopenharmony_ci } 830cc290419Sopenharmony_ci 831cc290419Sopenharmony_ci pub async fn put(connect_key: String, daemon_info: DaemonInfo) { 832cc290419Sopenharmony_ci let instance = Self::get_instance(); 833cc290419Sopenharmony_ci let mut map = instance.write().await; 834cc290419Sopenharmony_ci map.insert(connect_key, Arc::new(Mutex::new(daemon_info))); 835cc290419Sopenharmony_ci } 836cc290419Sopenharmony_ci 837cc290419Sopenharmony_ci pub async fn update(connect_key: String, 838cc290419Sopenharmony_ci conn_status: crate::task::ConnectStatus, 839cc290419Sopenharmony_ci version: String, 840cc290419Sopenharmony_ci dev_name: String, 841cc290419Sopenharmony_ci emg_msg: String, 842cc290419Sopenharmony_ci daemon_auth_status: String) -> bool { 843cc290419Sopenharmony_ci let instance = Self::get_instance(); 844cc290419Sopenharmony_ci let mut map = instance.write().await; 845cc290419Sopenharmony_ci if let Some(item) = map.get_mut(&connect_key) { 846cc290419Sopenharmony_ci let info = &mut *item.lock().await; 847cc290419Sopenharmony_ci info.conn_status = conn_status; 848cc290419Sopenharmony_ci info.version = version; 849cc290419Sopenharmony_ci info.dev_name = dev_name; 850cc290419Sopenharmony_ci info.emg_msg = emg_msg; 851cc290419Sopenharmony_ci info.daemon_auth_status = daemon_auth_status; 852cc290419Sopenharmony_ci true 853cc290419Sopenharmony_ci } else { 854cc290419Sopenharmony_ci false 855cc290419Sopenharmony_ci } 856cc290419Sopenharmony_ci } 857cc290419Sopenharmony_ci 858cc290419Sopenharmony_ci async fn get(connect_key: String) -> Option<DaemonInfo_> { 859cc290419Sopenharmony_ci let instance = Self::get_instance(); 860cc290419Sopenharmony_ci let map = instance.read().await; 861cc290419Sopenharmony_ci let key = if connect_key.as_str() == "any" && map.keys().len() == 1 { 862cc290419Sopenharmony_ci map.keys().last().unwrap() 863cc290419Sopenharmony_ci } else { 864cc290419Sopenharmony_ci &connect_key 865cc290419Sopenharmony_ci }; 866cc290419Sopenharmony_ci map.get(key).cloned() 867cc290419Sopenharmony_ci } 868cc290419Sopenharmony_ci 869cc290419Sopenharmony_ci pub async fn get_list(is_full: bool) -> Vec<String> { 870cc290419Sopenharmony_ci let instance = Self::get_instance(); 871cc290419Sopenharmony_ci let map = instance.read().await; 872cc290419Sopenharmony_ci let mut list = vec![]; 873cc290419Sopenharmony_ci for (key, info) in map.iter() { 874cc290419Sopenharmony_ci if is_full { 875cc290419Sopenharmony_ci let mut output = vec![key.as_str()]; 876cc290419Sopenharmony_ci let guard = info.lock().await; 877cc290419Sopenharmony_ci output.push(match guard.conn_type { 878cc290419Sopenharmony_ci ConnectType::Tcp => "TCP", 879cc290419Sopenharmony_ci ConnectType::Usb(_) => "USB", 880cc290419Sopenharmony_ci ConnectType::Uart => "UART", 881cc290419Sopenharmony_ci ConnectType::Bt => "BT", 882cc290419Sopenharmony_ci ConnectType::HostUsb(_) => "HOSTUSB", 883cc290419Sopenharmony_ci ConnectType::Bridge => "BRIDGE", 884cc290419Sopenharmony_ci }); 885cc290419Sopenharmony_ci if guard.daemon_auth_status == DAEOMN_UNAUTHORIZED { 886cc290419Sopenharmony_ci output.push("Unauthorized"); 887cc290419Sopenharmony_ci } else { 888cc290419Sopenharmony_ci output.push(match guard.conn_status { 889cc290419Sopenharmony_ci ConnectStatus::Connected => "Connected", 890cc290419Sopenharmony_ci ConnectStatus::Ready => "Ready", 891cc290419Sopenharmony_ci ConnectStatus::Offline => "Offline", 892cc290419Sopenharmony_ci ConnectStatus::Unknown => "Unknown", 893cc290419Sopenharmony_ci }); 894cc290419Sopenharmony_ci } 895cc290419Sopenharmony_ci if guard.dev_name.is_empty() { 896cc290419Sopenharmony_ci output.push("unknown..."); 897cc290419Sopenharmony_ci } else { 898cc290419Sopenharmony_ci let dev_name = guard.dev_name.as_str(); 899cc290419Sopenharmony_ci output.push(dev_name); 900cc290419Sopenharmony_ci }; 901cc290419Sopenharmony_ci output.push("hdc"); 902cc290419Sopenharmony_ci list.push(output.join("\t")); 903cc290419Sopenharmony_ci } else { 904cc290419Sopenharmony_ci let mut output = vec![key.as_str()]; 905cc290419Sopenharmony_ci let guard = info.lock().await; 906cc290419Sopenharmony_ci if guard.daemon_auth_status == DAEOMN_UNAUTHORIZED { 907cc290419Sopenharmony_ci output.push("Unauthorized"); 908cc290419Sopenharmony_ci } 909cc290419Sopenharmony_ci list.push(output.join("\t")); 910cc290419Sopenharmony_ci } 911cc290419Sopenharmony_ci } 912cc290419Sopenharmony_ci list 913cc290419Sopenharmony_ci } 914cc290419Sopenharmony_ci 915cc290419Sopenharmony_ci pub async fn get_session_id(connect_key: String) -> Option<u32> { 916cc290419Sopenharmony_ci let daemon_info = Self::get(connect_key).await?; 917cc290419Sopenharmony_ci let guard = daemon_info.lock().await; 918cc290419Sopenharmony_ci Some(guard.session_id) 919cc290419Sopenharmony_ci } 920cc290419Sopenharmony_ci 921cc290419Sopenharmony_ci pub async fn get_connect_key(session_id: u32) -> Option<String> { 922cc290419Sopenharmony_ci let instance = Self::get_instance(); 923cc290419Sopenharmony_ci let map = instance.read().await; 924cc290419Sopenharmony_ci for (key, info) in map.iter() { 925cc290419Sopenharmony_ci let lock = info.lock().await; 926cc290419Sopenharmony_ci if lock.session_id == session_id { 927cc290419Sopenharmony_ci return Some(key.clone()); 928cc290419Sopenharmony_ci } 929cc290419Sopenharmony_ci } 930cc290419Sopenharmony_ci None 931cc290419Sopenharmony_ci } 932cc290419Sopenharmony_ci} 933cc290419Sopenharmony_ci 934cc290419Sopenharmony_ciasync fn get_valid_session_id(connect_key: String, channel_id: u32) -> io::Result<u32> { 935cc290419Sopenharmony_ci match ConnectMap::get_session_id(connect_key).await { 936cc290419Sopenharmony_ci Some(session_id) => Ok(session_id), 937cc290419Sopenharmony_ci None => { 938cc290419Sopenharmony_ci transfer::send_channel_msg( 939cc290419Sopenharmony_ci channel_id, 940cc290419Sopenharmony_ci transfer::EchoLevel::FAIL, 941cc290419Sopenharmony_ci "Targets not found, please check the connect-key.".to_string(), 942cc290419Sopenharmony_ci ) 943cc290419Sopenharmony_ci .await?; 944cc290419Sopenharmony_ci transfer::TcpMap::end(channel_id).await; 945cc290419Sopenharmony_ci Err(Error::new(ErrorKind::Other, "session not found")) 946cc290419Sopenharmony_ci } 947cc290419Sopenharmony_ci } 948cc290419Sopenharmony_ci} 949