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 payload = task_info.params.join(" ").into_bytes();
245 transfer::put(
246 session_id,
247 TaskMessage {
248 channel_id: task_info.channel_id,
249 command: task_info.command,
250 payload,
251 },
252 )
253 .await;
254 Ok(())
255 }
256
channel_hilog_task(task_info: TaskInfo) -> io::Result<()>257 async fn channel_hilog_task(task_info: TaskInfo) -> io::Result<()> {
258 let session_id =
259 get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?;
260 let payload = if task_info.params.len() > 1 && task_info.params[1] == "-h" {
261 vec![104]
262 } else {
263 vec![0]
264 };
265 transfer::put(
266 session_id,
267 TaskMessage {
268 channel_id: task_info.channel_id,
269 command: HdcCommand::UnityHilog,
270 payload,
271 },
272 )
273 .await;
274 Ok(())
275 }
276
channel_bug_report_task(task_info: TaskInfo) -> io::Result<()>277 async fn channel_bug_report_task(task_info: TaskInfo) -> io::Result<()> {
278 let session_id =
279 get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?;
280 transfer::put(
281 session_id,
282 TaskMessage {
283 channel_id: task_info.channel_id,
284 command: HdcCommand::UnityBugreportInit,
285 payload: vec![],
286 },
287 )
288 .await;
289 Ok(())
290 }
291
channel_file_task(task_info: TaskInfo) -> io::Result<()>292 async fn channel_file_task(task_info: TaskInfo) -> io::Result<()> {
293 let session_id =
294 get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?;
295 let payload = task_info.params.join(" ").into_bytes();
296 match task_info.command {
297 HdcCommand::AppInit | HdcCommand::AppUninstall => {
298 match HostAppTaskMap::exist(session_id, task_info.channel_id).await {
299 Ok(true) => {}
300 Ok(false) => {
301 HostAppTaskMap::put(
302 session_id,
303 task_info.channel_id,
304 HostAppTask::new(session_id, task_info.channel_id),
305 )
306 .await;
307 }
308 Err(err) => {
309 return Err(io::Error::new(
310 io::ErrorKind::Other,
311 format!("call HostAppTaskMap::exist failed, {err:?}"),
312 ));
313 }
314 }
315 let _ = host_app::command_dispatch(
316 session_id,
317 task_info.channel_id,
318 task_info.command,
319 &payload,
320 payload.len() as u16,
321 )
322 .await;
323 }
324
325 HdcCommand::FileCheck | HdcCommand::FileInit => {
326 if !FileTaskMap::exsit(session_id, task_info.channel_id).await {
327 let mut task = HdcFile::new(session_id, task_info.channel_id);
328 task.transfer.server_or_daemon = true;
329 FileTaskMap::put(session_id, task_info.channel_id, task).await;
330 }
331 hdcfile::command_dispatch(
332 session_id,
333 task_info.channel_id,
334 task_info.command,
335 &payload,
336 payload.len() as u16,
337 )
338 .await;
339 return Ok(());
340 }
341 HdcCommand::FileBegin | HdcCommand::FileData | HdcCommand::FileFinish => {
342 hdcfile::command_dispatch(
343 session_id,
344 task_info.channel_id,
345 task_info.command,
346 &payload,
347 payload.len() as u16,
348 )
349 .await;
350 return Ok(());
351 }
352 _ => {
353 hdc::info!("other tasks, payload is {:#?}", payload);
354 }
355 }
356 Ok(())
357 }
358
send_to_daemon(task_info: TaskInfo, _cmd: HdcCommand, param_start_idx: usize, async_flag: bool) -> io::Result<()>359 async fn send_to_daemon(task_info: TaskInfo, _cmd: HdcCommand, param_start_idx: usize, async_flag: bool) -> io::Result<()> {
360 let session_id =
361 get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?;
362 hdc::info!("task_info params is {:?}", task_info);
363 transfer::put(
364 session_id,
365 TaskMessage {
366 channel_id: task_info.channel_id,
367 command: _cmd,
368 payload: task_info.params[param_start_idx..].join(" ").into_bytes(),
369 },
370 )
371 .await;
372 if async_flag {
373 transfer::TcpMap::end(task_info.channel_id).await;
374 }
375 Ok(())
376 }
377
channel_unity_task(task_info: TaskInfo) -> io::Result<()>378 async fn channel_unity_task(task_info: TaskInfo) -> io::Result<()> {
379 let session_id = match ConnectMap::get_session_id(task_info.connect_key.clone()).await {
380 Some(seid) => seid,
381 None => return Err(Error::new(ErrorKind::Other, "session not found")),
382 };
383 let cmd = task_info.params[1..]
384 .iter()
385 .map(|s| s.trim_end_matches('\0'))
386 .collect::<Vec<_>>()
387 .join(" ")
388 .into_bytes();
389 transfer::put(
390 session_id,
391 TaskMessage {
392 channel_id: task_info.channel_id,
393 command: task_info.command,
394 payload: cmd,
395 },
396 )
397 .await;
398 Ok(())
399 }
400
channel_shell_task(task_info: TaskInfo) -> io::Result<()>401 async fn channel_shell_task(task_info: TaskInfo) -> io::Result<()> {
402 let session_id =
403 get_valid_session_id(task_info.connect_key.clone(), task_info.channel_id).await?;
404 match task_info.command {
405 HdcCommand::UnityExecute => {
406 let cmd = task_info.params[1..]
407 .iter()
408 .map(|s| s.trim_end_matches('\0'))
409 .collect::<Vec<_>>()
410 .join(" ")
411 .into_bytes();
412 transfer::put(
413 session_id,
414 TaskMessage {
415 channel_id: task_info.channel_id,
416 command: task_info.command,
417 payload: cmd,
418 },
419 )
420 .await;
421 }
422 HdcCommand::ShellInit => {
423 transfer::put(
424 session_id,
425 TaskMessage {
426 channel_id: task_info.channel_id,
427 command: task_info.command,
428 payload: vec![0],
429 },
430 )
431 .await;
432 }
433 HdcCommand::ShellData => {
434 let payload = task_info.params.join("").into_bytes();
435 transfer::put(
436 session_id,
437 TaskMessage {
438 channel_id: task_info.channel_id,
439 command: task_info.command,
440 payload,
441 },
442 )
443 .await;
444 }
445 _ => {}
446 }
447
448 Ok(())
449 }
450
channel_connect_task(task_info: TaskInfo) -> io::Result<()>451 async fn channel_connect_task(task_info: TaskInfo) -> io::Result<()> {
452 let connect_key = task_info.params[1].trim_end_matches('\0').to_string();
453 if ConnectMap::get(connect_key.clone()).await.is_some() {
454 let ret = transfer::send_channel_msg(
455 task_info.channel_id,
456 transfer::EchoLevel::INFO,
457 "Target is connected, repeat operation".to_string(),
458 )
459 .await;
460 transfer::TcpMap::end(task_info.channel_id).await;
461 return ret;
462 }
463 start_tcp_daemon_session(connect_key, &task_info).await
464 }
465
usb_handle_deamon(ptr: u64, mut rx: mpsc::BoundedReceiver<(TaskMessage, u32)>, session_id: u32, connect_key: String) -> io::Result<()>466 pub async fn usb_handle_deamon(ptr: u64, mut rx: mpsc::BoundedReceiver<(TaskMessage, u32)>, session_id: u32, connect_key: String) -> io::Result<()> {
467 loop {
468 match rx.recv().await {
469 Ok((task_message, _index)) => {
470 hdc::debug!(
471 "in usb_handle_deamon, recv cmd: {:#?}, payload len: {}",
472 task_message.command,
473 task_message.payload.len(),
474 );
475 if let Err(e) = session_task_dispatch(task_message, session_id, connect_key.clone()).await {
476 hdc::error!("dispatch task failed: {}", e.to_string());
477 }
478 }
479 Err(e) => {
480 hdc::warn!("unpack task failed: {}", e.to_string());
481 ConnectMap::remove(connect_key.clone()).await;
482 host_usb::on_device_connected(ptr, connect_key, false);
483 return Err(Error::new(ErrorKind::Other, "recv error"));
484 }
485 };
486 }
487 }
488
start_usb_device_loop(ptr: u64, connect_key: String)489 pub async fn start_usb_device_loop(ptr: u64, connect_key: String) {
490 let session_id = utils::get_pseudo_random_u32();
491 let wr = host_usb::HostUsbWriter {
492 connect_key: connect_key.clone(),
493 ptr,
494 };
495 host_usb::HostUsbMap::start(session_id, wr).await;
496 let rx = host_usb::start_recv(ptr, connect_key.clone(), session_id);
497 let channel_id = utils::get_pseudo_random_u32();
498 hdc::info!("generate new session {} channel {}", session_id, channel_id);
499 start_handshake_with_daemon(connect_key.clone(), session_id, channel_id, ConnectType::HostUsb(connect_key.clone())).await;
500 let _ = ylong_runtime::spawn(usb_handle_deamon(ptr, rx, session_id, connect_key)).await;
501 }
502
start_tcp_daemon_session(connect_key: String, task_info: &TaskInfo) -> io::Result<()>503 async fn start_tcp_daemon_session(connect_key: String, task_info: &TaskInfo) -> io::Result<()> {
504 match TcpStream::connect(connect_key.clone()).await {
505 Err(_) => {
506 let ret = transfer::send_channel_msg(
507 task_info.channel_id,
508 transfer::EchoLevel::FAIL,
509 "Connect to daemon failed".to_string(),
510 )
511 .await;
512 transfer::TcpMap::end(task_info.channel_id).await;
513 ret
514 }
515 Ok(stream) => {
516 let session_id = utils::get_pseudo_random_u32();
517 let (rd, wr) = stream.into_split();
518 transfer::TcpMap::start(session_id, wr).await;
519
520 start_handshake_with_daemon(connect_key.clone(), session_id, task_info.channel_id, ConnectType::Tcp).await;
521 ylong_runtime::spawn(tcp_handle_deamon(rd, session_id, connect_key));
522 transfer::send_channel_msg(
523 task_info.channel_id,
524 transfer::EchoLevel::INFO,
525 "Connect OK".to_string(),
526 )
527 .await?;
528 transfer::TcpMap::end(task_info.channel_id).await;
529 Ok(())
530 }
531 }
532 }
533
channel_list_targets_task(task_info: TaskInfo) -> io::Result<()>534 async fn channel_list_targets_task(task_info: TaskInfo) -> io::Result<()> {
535 let is_full = task_info.params.contains(&"-v".to_string());
536 let target_list = ConnectMap::get_list(is_full).await;
537 let msg = if target_list.is_empty() {
538 "[Empty]".to_string()
539 } else {
540 target_list.join("\n")
541 };
542 transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?;
543 transfer::TcpMap::end(task_info.channel_id).await;
544 Ok(())
545 }
546
547 // check if any daemon connected and send the message to client for wait
channel_wait_for_any(task_info: TaskInfo) -> io::Result<()>548 async fn channel_wait_for_any(task_info: TaskInfo) -> io::Result<()> {
549 let target_list = ConnectMap::get_list(false).await;
550 if target_list.is_empty() {
551 hdc::info!("No any connected target");
552 let msg = "No connected target".to_string();
553 transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?;
554 } else if task_info.connect_key == "any" {
555 hdc::info!("Wait for connected target any");
556 let msg = "Wait for connected target any get ".to_string() + target_list[0].as_str();
557 transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?;
558 transfer::TcpMap::end(task_info.channel_id).await;
559 } else {
560 // wait for special connectkey
561 if target_list
562 .iter()
563 .any(|connect_key| connect_key == &task_info.connect_key)
564 {
565 hdc::info!("Wait for connected target is {}", task_info.connect_key);
566 let msg = "Wait for connected target is ".to_string() + task_info.connect_key.as_str();
567 transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?;
568 transfer::TcpMap::end(task_info.channel_id).await;
569 } else {
570 hdc::info!("No {} connected target ", task_info.connect_key);
571 let msg = "No connected target".to_string();
572 transfer::send_channel_msg(task_info.channel_id, transfer::EchoLevel::RAW, msg).await?;
573 }
574 }
575 Ok(())
576 }
577
tcp_handle_deamon( mut rd: SplitReadHalf, session_id: u32, connect_key: String, ) -> io::Result<()>578 async fn tcp_handle_deamon(
579 mut rd: SplitReadHalf,
580 session_id: u32,
581 connect_key: String,
582 ) -> io::Result<()> {
583 loop {
584 match transfer::tcp::unpack_task_message(&mut rd).await {
585 Ok(task_message) => {
586 // hdc::info!(
587 // "in tcp_handle_deamon, recv cmd: {:#?}, payload len: {}",
588 // task_message.command,
589 // task_message.payload.len(),
590 // );
591 if let Err(e) = session_task_dispatch(task_message, session_id, connect_key.clone()).await {
592 hdc::error!("dispatch task failed: {}", e.to_string());
593 }
594 }
595 Err(e) => {
596 hdc::warn!("unpack task failed: {}", e.to_string());
597 ConnectMap::remove(connect_key).await;
598 return Err(e);
599 }
600 };
601 }
602 }
603
session_task_dispatch(task_message: TaskMessage, session_id: u32, connect_key: String) -> io::Result<()>604 async fn session_task_dispatch(task_message: TaskMessage, session_id: u32, connect_key: String) -> io::Result<()> {
605 match task_message.command {
606 HdcCommand::KernelEcho => {
607 let data = task_message.payload[1..].to_vec();
608 let level_result = transfer::EchoLevel::convert_from_message_level(task_message.payload[0]);
609 match level_result {
610 Ok(level) => {
611 if let Ok(str) = String::from_utf8(data) {
612 if let Err(e) = transfer::send_channel_msg(
613 task_message.channel_id,
614 level,
615 str,
616 ).await {
617 hdc::error!("echo to client failed: {}", e.to_string());
618 };
619 }
620 }
621 Err(_) => {
622 return Err(Error::new(ErrorKind::Other, "message level invalid."));
623 }
624 }
625 }
626 HdcCommand::KernelEchoRaw | HdcCommand::UnityBugreportData => {
627 transfer::send_channel_data(task_message.channel_id, task_message.payload).await;
628 }
629 HdcCommand::KernelChannelClose => {
630 session_channel_close(task_message, session_id).await?;
631 }
632 HdcCommand::KernelHandshake => {
633 handshake_task(task_message, session_id, connect_key).await?;
634 }
635 HdcCommand::AppBegin
636 | HdcCommand::AppData
637 | HdcCommand::AppFinish
638 | HdcCommand::FileInit
639 | HdcCommand::FileBegin
640 | HdcCommand::FileData
641 | HdcCommand::FileCheck
642 | HdcCommand::FileFinish => {
643 session_file_task(task_message, session_id).await?;
644 }
645 HdcCommand::ForwardCheck
646 | HdcCommand::ForwardActiveMaster
647 | HdcCommand::ForwardActiveSlave
648 | HdcCommand::ForwardCheckResult
649 | HdcCommand::ForwardData => {
650 if HdcCommand::ForwardCheck == task_message.command {
651 let mut task = HdcForward::new(session_id, task_message.channel_id, true);
652 task.transfer.server_or_daemon = true;
653 ForwardTaskMap::update(session_id, task_message.channel_id, task).await;
654 }
655 session_forward_task(task_message, session_id).await?;
656 }
657 HdcCommand::ForwardSuccess => {
658 session_forward_success(task_message, session_id).await?;
659 }
660 _ => {}
661 }
662 Ok(())
663 }
664
session_forward_task(task_message: TaskMessage, session_id: u32) -> io::Result<()>665 async fn session_forward_task(task_message: TaskMessage, session_id: u32) -> io::Result<()> {
666 forward::command_dispatch(
667 session_id,
668 task_message.channel_id,
669 task_message.command,
670 &task_message.payload,
671 task_message.payload.len() as u16,
672 )
673 .await;
674 Ok(())
675 }
676
session_forward_success(task_message: TaskMessage, session_id: u32) -> io::Result<()>677 async fn session_forward_success(task_message: TaskMessage, session_id: u32) -> io::Result<()> {
678 let _ = forward::on_forward_success(task_message.clone(), session_id).await;
679 Ok(())
680 }
681
session_file_task(task_message: TaskMessage, session_id: u32) -> io::Result<()>682 async fn session_file_task(task_message: TaskMessage, session_id: u32) -> io::Result<()> {
683 match task_message.command {
684 HdcCommand::AppBegin | HdcCommand::AppFinish => {
685 let _ = host_app::command_dispatch(
686 session_id,
687 task_message.channel_id,
688 task_message.command,
689 &task_message.payload,
690 task_message.payload.len() as u16,
691 )
692 .await;
693 return Ok(());
694 }
695 HdcCommand::FileCheck | HdcCommand::FileInit => {
696 if !FileTaskMap::exsit(session_id, task_message.channel_id).await {
697 let mut task = HdcFile::new(session_id, task_message.channel_id);
698 task.transfer.server_or_daemon = true;
699 FileTaskMap::put(session_id, task_message.channel_id, task).await;
700 }
701
702 hdcfile::command_dispatch(
703 session_id,
704 task_message.channel_id,
705 task_message.command,
706 &task_message.payload,
707 task_message.payload.len() as u16,
708 )
709 .await;
710 return Ok(());
711 }
712 HdcCommand::FileBegin | HdcCommand::FileData | HdcCommand::FileFinish => {
713 hdcfile::command_dispatch(
714 session_id,
715 task_message.channel_id,
716 task_message.command,
717 &task_message.payload,
718 task_message.payload.len() as u16,
719 )
720 .await;
721 return Ok(());
722 }
723 _ => {
724 hdc::info!("other tasks");
725 }
726 }
727 /* ActionType 未定义,临时屏蔽
728 let channel_id = task_message.channel_id;
729 let command = task_message.command;
730
731 let opt = admin_session(ActionType::Query(session_id)).await;
732 if opt.is_none() {
733 admin_session(ActionType::Add(HdcSession::new(
734 session_id,
735 String::from(""),
736 NodeType::Server,
737 ConnectType::Tcp,
738 )))
739 .await;
740 }
741 let opt = admin_session(ActionType::Query(session_id)).await;
742
743 let arc = opt.unwrap();
744 let mut session = arc.lock().await;
745 if let std::collections::hash_map::Entry::Vacant(e) = session.map_tasks.entry(channel_id) {
746 match command {
747 HdcCommand::AppBegin => {
748 let mut task = HostAppTask::new(session_id, channel_id);
749 task.transfer.server_or_daemon = true;
750 e.insert(Arc::new(Mutex::new(task)));
751 }
752 HdcCommand::FileInit => {
753 let mut task = HdcFile::new(session_id, channel_id);
754 task.transfer.server_or_daemon = true;
755 e.insert(Arc::new(Mutex::new(task)));
756 }
757 _ => {
758 hdc::info!("other tasks");
759 }
760 }
761 }
762 let task = session.map_tasks.get(&channel_id).unwrap();
763 let task_ = &mut task.lock().await;
764 let cmd = task_message.payload;
765 let _ = task_.command_dispatch(command, &cmd[..], cmd.len() as u16);
766 */
767 Ok(())
768 }
769
session_channel_close(task_message: TaskMessage, session_id: u32) -> io::Result<()>770 pub async fn session_channel_close(task_message: TaskMessage, session_id: u32) -> io::Result<()> {
771 HostAppTaskMap::remove(session_id, task_message.channel_id).await;
772 if task_message.payload[0] > 0 {
773 let message = TaskMessage {
774 channel_id: task_message.channel_id,
775 command: HdcCommand::KernelChannelClose,
776 payload: vec![task_message.payload[0] - 1],
777 };
778 transfer::put(session_id, message).await;
779 }
780 hdc::info!("recv channel close {}", task_message.channel_id);
781 transfer::TcpMap::end(task_message.channel_id).await;
782 Ok(())
783 }
784
check_server_task(task_info: TaskInfo) -> io::Result<()>785 async fn check_server_task(task_info: TaskInfo) -> io::Result<()> {
786 let payload = [
787 u16::to_le_bytes(HdcCommand::KernelCheckServer as u16).as_slice(),
788 get_version().as_bytes(),
789 ]
790 .concat();
791 transfer::send_channel_data(task_info.channel_id, payload).await;
792 Ok(())
793 }
794
795 #[allow(unused)]
796 #[derive(Default)]
797 pub enum ConnectStatus {
798 #[default]
799 Unknown = 0,
800 Ready,
801 Connected,
802 Offline,
803 }
804
805 #[allow(unused)]
806 #[derive(Default)]
807 pub struct DaemonInfo {
808 pub session_id: u32,
809 pub conn_type: ConnectType,
810 pub conn_status: ConnectStatus,
811 pub dev_name: String,
812 pub version: String,
813 pub emg_msg: String,
814 pub daemon_auth_status: String,
815 }
816
817 type DaemonInfo_ = Arc<Mutex<DaemonInfo>>;
818 type ConnectMap_ = Arc<RwLock<HashMap<String, DaemonInfo_>>>;
819
820 pub struct ConnectMap {}
821 impl ConnectMap {
get_instance() -> ConnectMap_822 fn get_instance() -> ConnectMap_ {
823 static mut CONNECT_TYPE_MAP: Option<ConnectMap_> = None;
824 unsafe {
825 CONNECT_TYPE_MAP
826 .get_or_insert_with(|| Arc::new(RwLock::new(HashMap::new())))
827 .clone()
828 }
829 }
830
remove(connect_key: String)831 async fn remove(connect_key: String) {
832 let instance = Self::get_instance();
833 let mut map = instance.write().await;
834 map.remove(&connect_key);
835 }
836
put(connect_key: String, daemon_info: DaemonInfo)837 pub async fn put(connect_key: String, daemon_info: DaemonInfo) {
838 let instance = Self::get_instance();
839 let mut map = instance.write().await;
840 map.insert(connect_key, Arc::new(Mutex::new(daemon_info)));
841 }
842
update(connect_key: String, conn_status: crate::task::ConnectStatus, version: String, dev_name: String, emg_msg: String, daemon_auth_status: String) -> bool843 pub async fn update(connect_key: String,
844 conn_status: crate::task::ConnectStatus,
845 version: String,
846 dev_name: String,
847 emg_msg: String,
848 daemon_auth_status: String) -> bool {
849 let instance = Self::get_instance();
850 let mut map = instance.write().await;
851 if let Some(item) = map.get_mut(&connect_key) {
852 let info = &mut *item.lock().await;
853 info.conn_status = conn_status;
854 info.version = version;
855 info.dev_name = dev_name;
856 info.emg_msg = emg_msg;
857 info.daemon_auth_status = daemon_auth_status;
858 true
859 } else {
860 false
861 }
862 }
863
get(connect_key: String) -> Option<DaemonInfo_>864 async fn get(connect_key: String) -> Option<DaemonInfo_> {
865 let instance = Self::get_instance();
866 let map = instance.read().await;
867 let key = if connect_key.as_str() == "any" && map.keys().len() == 1 {
868 map.keys().last().unwrap()
869 } else {
870 &connect_key
871 };
872 map.get(key).cloned()
873 }
874
get_list(is_full: bool) -> Vec<String>875 pub async fn get_list(is_full: bool) -> Vec<String> {
876 let instance = Self::get_instance();
877 let map = instance.read().await;
878 let mut list = vec![];
879 for (key, info) in map.iter() {
880 if is_full {
881 let mut output = vec![key.as_str()];
882 let guard = info.lock().await;
883 output.push(match guard.conn_type {
884 ConnectType::Tcp => "TCP",
885 ConnectType::Usb(_) => "USB",
886 ConnectType::Uart => "UART",
887 ConnectType::Bt => "BT",
888 ConnectType::HostUsb(_) => "HOSTUSB",
889 ConnectType::Bridge => "BRIDGE",
890 });
891 if guard.daemon_auth_status == DAEOMN_UNAUTHORIZED {
892 output.push("Unauthorized");
893 } else {
894 output.push(match guard.conn_status {
895 ConnectStatus::Connected => "Connected",
896 ConnectStatus::Ready => "Ready",
897 ConnectStatus::Offline => "Offline",
898 ConnectStatus::Unknown => "Unknown",
899 });
900 }
901 if guard.dev_name.is_empty() {
902 output.push("unknown...");
903 } else {
904 let dev_name = guard.dev_name.as_str();
905 output.push(dev_name);
906 };
907 output.push("hdc");
908 list.push(output.join("\t"));
909 } else {
910 let mut output = vec![key.as_str()];
911 let guard = info.lock().await;
912 if guard.daemon_auth_status == DAEOMN_UNAUTHORIZED {
913 output.push("Unauthorized");
914 }
915 list.push(output.join("\t"));
916 }
917 }
918 list
919 }
920
get_session_id(connect_key: String) -> Option<u32>921 pub async fn get_session_id(connect_key: String) -> Option<u32> {
922 let daemon_info = Self::get(connect_key).await?;
923 let guard = daemon_info.lock().await;
924 Some(guard.session_id)
925 }
926
get_connect_key(session_id: u32) -> Option<String>927 pub async fn get_connect_key(session_id: u32) -> Option<String> {
928 let instance = Self::get_instance();
929 let map = instance.read().await;
930 for (key, info) in map.iter() {
931 let lock = info.lock().await;
932 if lock.session_id == session_id {
933 return Some(key.clone());
934 }
935 }
936 None
937 }
938 }
939
get_valid_session_id(connect_key: String, channel_id: u32) -> io::Result<u32>940 async fn get_valid_session_id(connect_key: String, channel_id: u32) -> io::Result<u32> {
941 match ConnectMap::get_session_id(connect_key).await {
942 Some(session_id) => Ok(session_id),
943 None => {
944 transfer::send_channel_msg(
945 channel_id,
946 transfer::EchoLevel::FAIL,
947 "Targets not found, please check the connect-key.".to_string(),
948 )
949 .await?;
950 transfer::TcpMap::end(channel_id).await;
951 Err(Error::new(ErrorKind::Other, "session not found"))
952 }
953 }
954 }
955