• 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 //! daemon
16 
17 extern crate panic_handler;
18 mod auth;
19 mod daemon_app;
20 mod daemon_unity;
21 use crate::jdwp::Jdwp;
22 mod mount;
23 mod shell;
24 mod task;
25 mod task_manager;
26 // mod sendmsg;
27 mod sys_para;
28 
29 use std::io::{self, ErrorKind, Write};
30 use std::sync::Arc;
31 use std::time::SystemTime;
32 
33 use crate::utils::hdc_log::*;
34 
35 use crate::shell::PtyMap;
36 use hdc::common::jdwp;
37 use hdc::config;
38 use hdc::config::TaskMessage;
39 #[cfg(feature = "emulator")]
40 use hdc::daemon_lib::bridge;
41 use hdc::transfer;
42 #[cfg(not(feature = "emulator"))]
43 use hdc::transfer::base::Reader;
44 #[cfg(not(feature = "emulator"))]
45 use hdc::transfer::uart::UartReader;
46 #[cfg(not(feature = "emulator"))]
47 use hdc::transfer::uart_wrapper;
48 use hdc::utils;
49 
50 use crate::auth::clear_auth_pub_key_file;
51 use crate::sys_para::*;
52 use log::LevelFilter;
53 #[cfg(not(feature = "emulator"))]
54 use std::ffi::c_int;
55 use std::ffi::CString;
56 #[cfg(not(feature = "emulator"))]
57 use ylong_runtime::net::{TcpListener, TcpStream};
58 #[cfg(not(feature = "emulator"))]
59 use ylong_runtime::sync::mpsc;
60 
61 extern "C" {
62     #[cfg(not(feature = "emulator"))]
NeedDropRootPrivileges() -> c_int63     fn NeedDropRootPrivileges() -> c_int;
64 }
65 
66 #[cfg(not(feature = "emulator"))]
need_drop_root_privileges()67 fn need_drop_root_privileges() {
68     hdc::info!("need_drop_root_privileges");
69     unsafe {
70         NeedDropRootPrivileges();
71     }
72 }
73 
handle_message(res: io::Result<TaskMessage>, session_id: u32) -> io::Result<()>74 async fn handle_message(res: io::Result<TaskMessage>, session_id: u32) -> io::Result<()> {
75     match res {
76         Ok(msg) => {
77             if let Err(e) = task::dispatch_task(msg, session_id).await {
78                 hdc::error!("dispatch task failed: {}", e.to_string());
79             }
80         }
81         Err(e) => {
82             hdc::debug!("clear pty map: {}", session_id);
83             if e.kind() == ErrorKind::Other {
84                 hdc::warn!("unpack task failed: {}", e.to_string());
85                 PtyMap::clear(session_id).await;
86                 return Err(e);
87             }
88         }
89     };
90     Ok(())
91 }
92 
jdwp_daemon_start(lock_value: Arc<Jdwp>)93 async fn jdwp_daemon_start(lock_value: Arc<Jdwp>) {
94     lock_value.init().await;
95 }
96 
97 #[cfg(feature = "emulator")]
bridge_daemon_start() -> io::Result<()>98 async fn bridge_daemon_start() -> io::Result<()> {
99     hdc::info!("bridge_daemon_start start...");
100     let ptr = bridge::init_bridge() as u64;
101     hdc::info!("bridge_daemon_start ptr:{}", ptr);
102     let pipe_read_fd = bridge::start_listen(ptr);
103     hdc::info!("bridge_daemon_start pipe_read_fd:{}", pipe_read_fd);
104     if pipe_read_fd < 0 {
105         hdc::error!("daemon bridge listen fail.");
106         return Err(std::io::Error::new(
107             ErrorKind::Other,
108             "daemon bridge listen fail.",
109         ));
110     }
111     loop {
112         hdc::info!("bridge_daemon_start loop...");
113         let client_fd_for_hdc_server = bridge::accept_server_socket_fd(ptr, pipe_read_fd);
114         if client_fd_for_hdc_server < 0 {
115             hdc::error!("bridge_daemon_start accept client fd for hdc server fail...");
116             break;
117         }
118         let client_fd = bridge::init_client_fd(ptr, client_fd_for_hdc_server);
119         if client_fd < 0 {
120             hdc::error!("bridge_daemon_start init client fd fail...");
121             break;
122         }
123         ylong_runtime::spawn(bridge_handle_client(
124             ptr,
125             client_fd,
126             client_fd_for_hdc_server,
127         ));
128     }
129     bridge::stop(ptr);
130     Ok(())
131 }
132 
133 #[cfg(feature = "emulator")]
bridge_handle_client(ptr: u64, fd: i32, client_fd: i32) -> io::Result<()>134 async fn bridge_handle_client(ptr: u64, fd: i32, client_fd: i32) -> io::Result<()> {
135     hdc::info!("bridge_handle_client start...");
136     let rd = bridge::BridgeReader { ptr, fd };
137     let wr = bridge::BridgeWriter { ptr, fd };
138     let recv_msg = bridge::unpack_task_message(&rd).await?;
139     let (session_id, send_msg) = auth::handshake_init(recv_msg).await?;
140     let channel_id = send_msg.channel_id;
141     bridge::BridgeMap::start(session_id, wr).await;
142     transfer::put(session_id, send_msg).await;
143 
144     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
145         transfer::put(
146             session_id,
147             TaskMessage {
148                 channel_id,
149                 command: config::HdcCommand::KernelChannelClose,
150                 payload: vec![0],
151             },
152         )
153         .await;
154     }
155 
156     loop {
157         let ret = handle_message(transfer::tcp::unpack_task_message(&rd).await, session_id).await;
158         if ret.is_err() {
159             unsafe {
160                 libc::close(fd);
161                 libc::close(client_fd);
162             }
163             break;
164         }
165     }
166     Ok(())
167 }
168 
169 #[cfg(not(feature = "emulator"))]
tcp_handle_client(stream: TcpStream) -> io::Result<()>170 async fn tcp_handle_client(stream: TcpStream) -> io::Result<()> {
171     let (mut rd, wr) = stream.into_split();
172     let msg = transfer::tcp::unpack_task_message(&mut rd).await?;
173     let session_id = auth::get_session_id_from_msg(&msg).await?;
174     hdc::info!(
175         "tcp_handle_client session_id {session_id}, channel_id {}",
176         msg.channel_id
177     );
178     transfer::TcpMap::start(session_id, wr).await;
179     handle_message(Ok(msg), session_id).await?;
180 
181     loop {
182         handle_message(
183             transfer::tcp::unpack_task_message(&mut rd).await,
184             session_id,
185         )
186         .await?;
187     }
188 }
189 
190 #[cfg(not(feature = "emulator"))]
tcp_daemon_start(port: u16) -> io::Result<()>191 async fn tcp_daemon_start(port: u16) -> io::Result<()> {
192     hdc::info!("tcp_daemon_start port = {:#?}", port);
193     let saddr = format!("0.0.0.0:{}", port);
194     let listener = TcpListener::bind(saddr.clone()).await?;
195     let random_port = listener.local_addr()?.port();
196     hdc::info!(
197         "daemon binds on saddr = {:#?}, port = {:#?}",
198         saddr,
199         random_port
200     );
201     if !set_dev_item(config::ENV_HOST_PORT, &random_port.to_string()) {
202         hdc::error!("set tcp port: {} failed.", port);
203     }
204     loop {
205         let (stream, addr) = listener.accept().await?;
206         hdc::info!("accepted client {addr}");
207         ylong_runtime::spawn(async {
208             if let Err(e) = tcp_handle_client(stream).await {
209                 hdc::error!("tcp_handle_client {e:?}");
210             }
211         });
212     }
213 }
214 
215 #[cfg(not(feature = "emulator"))]
uart_daemon_start() -> io::Result<()>216 async fn uart_daemon_start() -> io::Result<()> {
217     loop {
218         let fd = transfer::uart::uart_init()?;
219         if let Err(e) = uart_handle_client(fd).await {
220             hdc::error!("uart_handle_client failed, {:?}", e);
221         }
222         transfer::uart::uart_close(fd);
223     }
224 }
225 
226 #[cfg(not(feature = "emulator"))]
uart_handshake( handshake_message: TaskMessage, fd: i32, rd: &UartReader, package_index: u32, ) -> io::Result<u32>227 async fn uart_handshake(
228     handshake_message: TaskMessage,
229     fd: i32,
230     rd: &UartReader,
231     package_index: u32,
232 ) -> io::Result<u32> {
233     let (session_id, send_msg) = auth::handshake_init(handshake_message).await?;
234     let channel_id = send_msg.channel_id;
235 
236     let wr = transfer::uart::UartWriter { fd };
237     transfer::start_uart(session_id, wr).await;
238     transfer::start_session(session_id).await;
239 
240     let Some(head) = rd.head.clone() else {
241         return Err(std::io::Error::new(
242             ErrorKind::Other,
243             "rd head clone failed",
244         ));
245     };
246     uart_wrapper::on_read_head(head).await;
247     transfer::wrap_put(session_id, send_msg, package_index, 0).await;
248 
249     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
250         transfer::put(
251             session_id,
252             TaskMessage {
253                 channel_id,
254                 command: config::HdcCommand::KernelChannelClose,
255                 payload: vec![0],
256             },
257         )
258         .await;
259     }
260     Ok(session_id)
261 }
262 
263 #[cfg(not(feature = "emulator"))]
uart_handle_client(fd: i32) -> io::Result<()>264 async fn uart_handle_client(fd: i32) -> io::Result<()> {
265     let mut rd = transfer::uart::UartReader { fd, head: None };
266     let (packet_size, package_index) = rd.check_protocol_head()?;
267     let (tx, mut rx) = mpsc::bounded_channel::<TaskMessage>(config::USB_QUEUE_LEN);
268     ylong_runtime::spawn(async move {
269         let mut rd = transfer::uart::UartReader { fd, head: None };
270         if let Err(e) =
271             transfer::base::unpack_task_message_lock(&mut rd, packet_size, tx.clone()).await
272         {
273             hdc::warn!("unpack task failed: {}, reopen fd...", e.to_string());
274         }
275     });
276     let session_id;
277     match rx.recv().await {
278         Ok(handshake_message) => {
279             let _ = rx.recv().await;
280             hdc::info!("uart handshake_message:{:?}", handshake_message);
281             session_id = uart_handshake(handshake_message.clone(), fd, &rd, package_index).await?;
282         }
283         Err(e) => {
284             hdc::info!("uart handshake error, {e:?}");
285             return Err(std::io::Error::new(
286                 ErrorKind::Other,
287                 format!("uart recv handshake error, {e:?}"),
288             ));
289         }
290     }
291 
292     uart_wrapper::stop_other_session(session_id).await;
293     let mut real_session_id = session_id;
294     loop {
295         let (packet_size, _package_index) = rd.check_protocol_head()?;
296         let Some(head) = rd.head.clone() else {
297             return Err(std::io::Error::new(ErrorKind::Other, "rd head clone file"));
298         };
299         let package_index = head.package_index;
300         let session_id = head.session_id;
301         uart_wrapper::on_read_head(head).await;
302         if real_session_id != session_id {
303             hdc::info!("real_session_id:{real_session_id}, session_id:{session_id}");
304             uart_wrapper::stop_other_session(session_id).await;
305         }
306         if packet_size == 0 {
307             continue;
308         }
309 
310         let (tx, mut rx) = mpsc::bounded_channel::<TaskMessage>(config::USB_QUEUE_LEN);
311         ylong_runtime::spawn(async move {
312             let mut rd = transfer::uart::UartReader { fd, head: None };
313             if let Err(e) =
314                 transfer::base::unpack_task_message_lock(&mut rd, packet_size, tx.clone()).await
315             {
316                 hdc::warn!("uart read uart taskmessage error:{:?}", e);
317             }
318         });
319 
320         loop {
321             match rx.recv().await {
322                 Ok(message) => {
323                     if message.command == config::HdcCommand::UartFinish {
324                         break;
325                     }
326 
327                     if message.command == config::HdcCommand::KernelHandshake {
328                         real_session_id =
329                             uart_handshake(message.clone(), fd, &rd, package_index).await?;
330                         hdc::info!("real_session_id:{real_session_id:?}");
331                         continue;
332                     }
333                     let command = message.command;
334                     ylong_runtime::spawn(async move {
335                         if let Err(e) = task::dispatch_task(message, real_session_id).await {
336                             log::error!("dispatch task({:?}) fail: {:?}", command, e);
337                         }
338                     });
339                 }
340                 Err(e) => {
341                     let error_msg = format!("uart recv error: {e:?}");
342                     hdc::info!("{error_msg}");
343                     return Err(std::io::Error::new(ErrorKind::Other, error_msg));
344                 }
345             }
346         }
347     }
348 }
349 
350 #[cfg(not(feature = "emulator"))]
usb_daemon_start() -> io::Result<()>351 async fn usb_daemon_start() -> io::Result<()> {
352     loop {
353         let ret = transfer::usb::usb_init();
354         match ret {
355             Ok((config_fd, bulkin_fd, bulkout_fd)) => {
356                 let _ = usb_handle_client(config_fd, bulkin_fd, bulkout_fd).await;
357                 transfer::usb::usb_close(config_fd, bulkin_fd, bulkout_fd);
358             }
359             Err(e) => {
360                 hdc::error!("usb inut failure and restart hdcd error is {:?}", e);
361                 std::process::exit(0);
362             }
363         }
364     }
365 }
366 
367 #[cfg(not(feature = "emulator"))]
usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) -> io::Result<()>368 async fn usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) -> io::Result<()> {
369     let _rd = transfer::usb::UsbReader { fd: bulkin_fd };
370     let mut rx = transfer::usb_start_recv(bulkin_fd, 0);
371     let mut cur_session_id = 0;
372     loop {
373         match rx.recv().await {
374             Ok((msg, _index)) => {
375                 if msg.command == config::HdcCommand::KernelHandshake {
376                     if let Ok(session_id_in_msg) = auth::get_session_id_from_msg(&msg).await {
377                         if session_id_in_msg != cur_session_id {
378                             hdc::info!("new session(usb) id:{}", session_id_in_msg);
379                             let wr = transfer::usb::UsbWriter { fd: bulkout_fd };
380                             transfer::UsbMap::start(session_id_in_msg, wr).await;
381                             task_manager::free_session(
382                                 config::ConnectType::Usb("some_mount_point".to_string()),
383                                 cur_session_id,
384                             )
385                             .await;
386                             cur_session_id = session_id_in_msg;
387                         }
388                     }
389                 }
390                 ylong_runtime::spawn(async move {
391                     if let Err(e) = task::dispatch_task(msg, cur_session_id).await {
392                         hdc::error!("dispatch task failed: {}", e.to_string());
393                     }
394                 });
395             }
396             Err(e) => {
397                 hdc::warn!("unpack task failed: {}", e.to_string());
398                 break;
399             }
400         }
401     }
402     task_manager::free_session(
403         config::ConnectType::Usb("some_mount_point".to_string()),
404         cur_session_id,
405     )
406     .await;
407     Ok(())
408 }
409 
logger_init(log_level: LevelFilter)410 fn logger_init(log_level: LevelFilter) {
411     env_logger::Builder::new()
412         .format(|buf, record| {
413             let ts = humantime::format_rfc3339_millis(SystemTime::now()).to_string();
414             let level = &record.level().to_string()[..1];
415             let file = record.file().unwrap_or("unknown");
416             writeln!(
417                 buf,
418                 "{} {} {} {}:{} - {}",
419                 &ts[..10],
420                 &ts[11..23],
421                 level,
422                 file.split('/').last().unwrap_or("unknown"),
423                 record.line().unwrap_or(0),
424                 record.args()
425             )
426         })
427         .filter(None, log_level)
428         .init();
429 }
430 
get_logger_lv() -> LevelFilter431 fn get_logger_lv() -> LevelFilter {
432     let lv = std::env::var_os("HDCD_LOGLV")
433         .unwrap_or_default()
434         .to_str()
435         .unwrap_or_default()
436         .parse::<usize>()
437         .unwrap_or(0_usize);
438     config::LOG_LEVEL_ORDER[lv]
439 }
440 
441 #[cfg(not(feature = "emulator"))]
get_tcp_port() -> u16442 fn get_tcp_port() -> u16 {
443     let (ret, host_port) = get_dev_item(config::ENV_HOST_PORT, "_");
444     if !ret || host_port == "_" {
445         hdc::error!(
446             "get host port failed, will use default port {}.",
447             config::DAEMON_PORT
448         );
449         return config::DAEMON_PORT;
450     }
451 
452     let str = host_port.trim();
453     hdc::info!("get_tcp_port from prop, value:{}", str);
454     let mut end = str.len();
455     for i in 0..str.len() {
456         let c = str.as_bytes()[i];
457         if !c.is_ascii_digit() {
458             end = i;
459             break;
460         }
461     }
462     let str2 = str[0..end].to_string();
463     let number = str2.parse::<u16>();
464     if let Ok(num) = number {
465         hdc::info!("get host port:{} success", num);
466         return num;
467     }
468 
469     hdc::error!(
470         "convert host port failed, will use default port {}.",
471         config::DAEMON_PORT
472     );
473     config::DAEMON_PORT
474 }
475 
main()476 fn main() {
477     let args: Vec<String> = std::env::args().collect();
478     panic_handler::init();
479     if args.len() == 2 && args[1] == "-v" {
480         println!("{}", config::get_version());
481         return;
482     }
483     logger_init(get_logger_lv());
484 
485     let _ = ylong_runtime::builder::RuntimeBuilder::new_multi_thread()
486         .worker_stack_size(16 * 1024 * 1024)
487         .worker_num(20)
488         .build_global();
489 
490     #[cfg(not(feature = "emulator"))]
491     need_drop_root_privileges();
492     clear_auth_pub_key_file();
493 
494     ylong_runtime::block_on(async {
495         #[cfg(not(feature = "emulator"))]
496         let tcp_task = ylong_runtime::spawn(async {
497             if let Err(e) = tcp_daemon_start(get_tcp_port()).await {
498                 hdc::error!("[Fail]tcp daemon failed: {}", e);
499             }
500         });
501         #[cfg(not(feature = "emulator"))]
502         let usb_task = ylong_runtime::spawn(async {
503             if let Err(e) = usb_daemon_start().await {
504                 hdc::error!("[Fail]usb daemon failed: {}", e);
505             }
506         });
507         #[cfg(not(feature = "emulator"))]
508         let uart_task = ylong_runtime::spawn(async {
509             if let Err(e) = uart_daemon_start().await {
510                 hdc::error!("[Fail]uart daemon failed: {}", e);
511             }
512         });
513         #[cfg(feature = "emulator")]
514         hdc::info!("daemon main emulator, start bridge daemon.");
515         #[cfg(feature = "emulator")]
516         let bridge_task = ylong_runtime::spawn(async {
517             if let Err(e) = bridge_daemon_start().await {
518                 hdc::error!("[Fail]bridge daemon failed: {}", e);
519             }
520         });
521         let lock_value = Jdwp::get_instance();
522         let jdwp_server_task = ylong_runtime::spawn(async {
523             jdwp_daemon_start(lock_value).await;
524         });
525         #[cfg(not(feature = "emulator"))]
526         let _ = tcp_task.await;
527         #[cfg(not(feature = "emulator"))]
528         let _ = usb_task.await;
529         #[cfg(not(feature = "emulator"))]
530         let _ = uart_task.await;
531         #[cfg(feature = "emulator")]
532         let _ = bridge_task.await;
533         let _ = jdwp_server_task.await;
534     });
535 }
536