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
channel_task_dispatch(task_info: TaskInfo) -> io::Result<()>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
channel_forward_task(task_info: TaskInfo) -> io::Result<()>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
channel_forward_remove(task_info: TaskInfo, forward_or_reverse: bool) -> io::Result<()>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
channel_forward_list(task_info: TaskInfo, forward_or_reverse: bool) -> io::Result<()>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
channel_jdwp_task(task_info: TaskInfo) -> io::Result<()>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
channel_hilog_task(task_info: TaskInfo) -> io::Result<()>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
channel_bug_report_task(task_info: TaskInfo) -> io::Result<()>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
channel_file_task(task_info: TaskInfo) -> io::Result<()>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
send_to_daemon(task_info: TaskInfo, _cmd: HdcCommand, param_start_idx: usize, async_flag: bool) -> io::Result<()>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
channel_unity_task(task_info: TaskInfo) -> io::Result<()>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
channel_shell_task(task_info: TaskInfo) -> io::Result<()>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
channel_connect_task(task_info: TaskInfo) -> io::Result<()>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
usb_handle_deamon(ptr: u64, mut rx: mpsc::BoundedReceiver<(TaskMessage, u32)>, session_id: u32, connect_key: String) -> io::Result<()>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
start_usb_device_loop(ptr: u64, connect_key: String)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
start_tcp_daemon_session(connect_key: String, task_info: &TaskInfo) -> io::Result<()>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
channel_list_targets_task(task_info: TaskInfo) -> io::Result<()>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
channel_wait_for_any(task_info: TaskInfo) -> io::Result<()>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
tcp_handle_deamon( mut rd: SplitReadHalf, session_id: u32, connect_key: String, ) -> io::Result<()>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
session_task_dispatch(task_message: TaskMessage, session_id: u32, connect_key: String) -> io::Result<()>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
session_forward_task(task_message: TaskMessage, session_id: u32) -> io::Result<()>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
session_forward_success(task_message: TaskMessage, session_id: u32) -> io::Result<()>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
session_file_task(task_message: TaskMessage, session_id: u32) -> io::Result<()>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
session_channel_close(task_message: TaskMessage, session_id: u32) -> io::Result<()>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
check_server_task(task_info: TaskInfo) -> io::Result<()>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_instance() -> ConnectMap_816 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
remove(connect_key: String)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
put(connect_key: String, daemon_info: DaemonInfo)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
update(connect_key: String, conn_status: crate::task::ConnectStatus, version: String, dev_name: String, emg_msg: String, daemon_auth_status: String) -> bool837 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
get(connect_key: String) -> Option<DaemonInfo_>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
get_list(is_full: bool) -> Vec<String>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
get_session_id(connect_key: String) -> Option<u32>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
get_connect_key(session_id: u32) -> Option<String>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
get_valid_session_id(connect_key: String, channel_id: u32) -> io::Result<u32>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