• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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