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