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