• 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 mod auth;
18 mod daemon_app;
19 mod daemon_unity;
20 use crate::jdwp::Jdwp;
21 mod mount;
22 mod shell;
23 mod task;
24 // mod sendmsg;
25 mod sys_para;
26 
27 use std::io::{self, ErrorKind, Write};
28 use std::sync::Arc;
29 use std::time::SystemTime;
30 
31 use crate::utils::hdc_log::*;
32 
33 use hdc::common::jdwp;
34 use hdc::config;
35 use hdc::config::TaskMessage;
36 use hdc::transfer;
37 use hdc::transfer::uart::UartReader;
38 use hdc::transfer::base::Reader;
39 use hdc::transfer::uart_wrapper;
40 use hdc::utils;
41 
42 use log::LevelFilter;
43 use std::ffi::CString;
44 use ylong_runtime::net::{TcpListener, TcpStream};
45 use ylong_runtime::sync::mpsc;
46 use std::ffi::c_int;
47 
48 extern "C" {
NeedDropRootPrivileges()-> c_int49     fn NeedDropRootPrivileges()-> c_int;
50 }
51 
need_drop_root_privileges()52 fn need_drop_root_privileges() {
53     hdc::info!("need_drop_root_privileges");
54     unsafe {
55         NeedDropRootPrivileges();
56     }
57 }
58 
handle_message(res: io::Result<TaskMessage>, session_id: u32) -> io::Result<()>59 async fn handle_message(res: io::Result<TaskMessage>, session_id: u32) -> io::Result<()> {
60     match res {
61         Ok(msg) => {
62             if let Err(e) = task::dispatch_task(msg, session_id).await {
63                 hdc::error!("dispatch task failed: {}", e.to_string());
64             }
65         }
66         Err(e) => {
67             if e.kind() == ErrorKind::Other {
68                 hdc::warn!("unpack task failed: {}", e.to_string());
69                 return Err(e);
70             }
71         }
72     };
73     Ok(())
74 }
75 
jdwp_daemon_start(lock_value: Arc<Jdwp>)76 async fn jdwp_daemon_start(lock_value: Arc<Jdwp>) {
77     lock_value.init().await;
78 }
79 
tcp_handle_client(stream: TcpStream) -> io::Result<()>80 async fn tcp_handle_client(stream: TcpStream) -> io::Result<()> {
81     let (mut rd, wr) = stream.into_split();
82     let recv_msg = transfer::tcp::unpack_task_message(&mut rd).await?;
83 
84     let (session_id, send_msg) = auth::handshake_init(recv_msg).await?;
85     let channel_id = send_msg.channel_id;
86 
87     transfer::TcpMap::start(session_id, wr).await;
88     transfer::put(session_id, send_msg).await;
89     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
90         transfer::put(
91             session_id,
92             TaskMessage {
93                 channel_id,
94                 command: config::HdcCommand::KernelChannelClose,
95                 payload: vec![0],
96             },
97         )
98         .await;
99     }
100 
101     loop {
102         handle_message(
103             transfer::tcp::unpack_task_message(&mut rd).await,
104             session_id,
105         )
106         .await?;
107     }
108 }
109 
tcp_daemon_start(port: u16) -> io::Result<()>110 async fn tcp_daemon_start(port: u16) -> io::Result<()> {
111     let saddr = format!("0.0.0.0:{}", port);
112     let listener = TcpListener::bind(saddr.clone()).await?;
113     hdc::info!("daemon binds on {saddr}");
114     loop {
115         let (stream, addr) = listener.accept().await?;
116         hdc::info!("accepted client {addr}");
117         ylong_runtime::spawn(tcp_handle_client(stream));
118     }
119 }
120 
uart_daemon_start() -> io::Result<()>121 async fn uart_daemon_start() -> io::Result<()> {
122     loop {
123         let fd = transfer::uart::uart_init()?;
124         let _ret = uart_handle_client(fd).await;
125         transfer::uart::uart_close(fd);
126     }
127 }
128 
uart_handshake( handshake_message: TaskMessage, fd: i32, rd: &UartReader, package_index: u32, ) -> io::Result<u32>129 async fn uart_handshake(
130     handshake_message: TaskMessage,
131     fd: i32,
132     rd: &UartReader,
133     package_index: u32,
134 ) -> io::Result<u32> {
135     let (session_id, send_msg) = auth::handshake_init(handshake_message).await?;
136     let channel_id = send_msg.channel_id;
137 
138     let wr = transfer::uart::UartWriter { fd };
139     transfer::start_uart(session_id, wr).await;
140     transfer::start_session(session_id).await;
141 
142     let head = rd.head.clone().unwrap();
143     uart_wrapper::on_read_head(head).await;
144     transfer::wrap_put(session_id, send_msg, package_index, 0).await;
145 
146     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
147         transfer::put(
148             session_id,
149             TaskMessage {
150                 channel_id,
151                 command: config::HdcCommand::KernelChannelClose,
152                 payload: vec![0],
153             },
154         )
155         .await;
156     }
157     Ok(session_id)
158 }
159 
uart_handle_client(fd: i32) -> io::Result<()>160 async fn uart_handle_client(fd: i32) -> io::Result<()> {
161     let mut rd = transfer::uart::UartReader { fd, head: None };
162     let (packet_size, package_index) = rd.check_protocol_head()?;
163     let (tx, mut rx) = mpsc::bounded_channel::<TaskMessage>(config::USB_QUEUE_LEN);
164     ylong_runtime::spawn(async move {
165         let mut rd = transfer::uart::UartReader { fd, head: None };
166         if let Err(e) =
167             transfer::base::unpack_task_message_lock(&mut rd, packet_size, tx.clone()).await
168         {
169             hdc::warn!("unpack task failed: {}, reopen fd...", e.to_string());
170             println!("handshake error:{:#?}", e);
171         }
172     });
173     let session_id;
174     match rx.recv().await {
175         Ok(handshake_message) => {
176             let _ = rx.recv().await;
177             println!("uart handshake_message:{:#?}", handshake_message);
178             session_id = uart_handshake(handshake_message.clone(), fd, &rd, package_index).await?;
179         }
180         Err(_e) => {
181             println!("uart handshake error");
182             return Err(std::io::Error::new(ErrorKind::Other, "uart recv handshake error"));
183         }
184     }
185 
186     uart_wrapper::stop_other_session(session_id).await;
187     let mut real_session_id = session_id;
188     loop {
189         let (packet_size, _package_index) = rd.check_protocol_head()?;
190         let head = rd.head.clone().unwrap();
191         let package_index = head.package_index;
192         let session_id = head.session_id;
193         uart_wrapper::on_read_head(head).await;
194         if real_session_id != session_id {
195             uart_wrapper::stop_other_session(session_id).await;
196         }
197         if packet_size == 0 {
198             continue;
199         }
200 
201         let (tx, mut rx) = mpsc::bounded_channel::<TaskMessage>(config::USB_QUEUE_LEN);
202         ylong_runtime::spawn(async move {
203             let mut rd = transfer::uart::UartReader { fd, head: None };
204             if let Err(e) =
205                 transfer::base::unpack_task_message_lock(&mut rd, packet_size, tx.clone()).await
206             {
207                 hdc::warn!("unpack task failed: {}, reopen fd...", e.to_string());
208                 println!("uart read uart taskmessage error:{:#?}", e);
209             }
210         });
211 
212         loop {
213                 match rx.recv().await {
214                     Ok(message) => {
215                         if message.command == config::HdcCommand::UartFinish {
216                             break;
217                         }
218 
219                         if message.command == config::HdcCommand::KernelHandshake {
220                             real_session_id =
221                                 uart_handshake(message.clone(), fd, &rd, package_index).await?;
222                             continue;
223                         }
224                         let command = message.command;
225                         ylong_runtime::spawn(async move {
226                             if let Err(e) = task::dispatch_task(message, real_session_id).await {
227                                 log::error!("dispatch task failed: {}", e.to_string());
228                                 println!("dispatch task({:#?}) fail: {:#?}", command, e);
229                             }
230                         });
231                     }
232                     Err(_e) => {
233                         println!("uart recv error: {:#?}", _e);
234                         return Err(std::io::Error::new(ErrorKind::Other, "RecvError"));
235                     }
236                 }
237             }
238         }
239     }
240 
usb_daemon_start() -> io::Result<()>241 async fn usb_daemon_start() -> io::Result<()> {
242     loop {
243         let ret = transfer::usb::usb_init();
244         match ret {
245             Ok((config_fd, bulkin_fd, bulkout_fd)) => {
246                 let _ = usb_handle_client(config_fd, bulkin_fd, bulkout_fd).await;
247                 transfer::usb::usb_close(config_fd, bulkin_fd, bulkout_fd);
248             }
249             Err(e) => {
250                 hdc::error!("usb inut failure and restart hdcd error is {:#?}", e);
251                 std::process::exit(0);
252             }
253         }
254     }
255 }
256 
usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) -> io::Result<()>257 async fn usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) -> io::Result<()> {
258     let _rd = transfer::usb::UsbReader { fd: bulkin_fd };
259     let wr = transfer::usb::UsbWriter { fd: bulkout_fd };
260 
261     let mut rx = transfer::usb_start_recv(bulkin_fd, 0);
262     let (recv_msg, _package_index) = match rx.recv().await {
263         Ok((msg, index)) => (msg, index),
264         Err(_) => {
265             return Err(utils::error_other("usb recv failed, reopen...".to_string()));
266         }
267     };
268 
269     // let recv_msg = transfer::base::unpack_task_message(&rd)?;
270     let (session_id, send_msg) = auth::handshake_init(recv_msg).await?;
271     let channel_id = send_msg.channel_id;
272 
273     transfer::UsbMap::start(session_id, wr).await;
274     transfer::put(session_id, send_msg).await;
275 
276     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
277         transfer::put(
278             session_id,
279             TaskMessage {
280                 channel_id,
281                 command: config::HdcCommand::KernelChannelClose,
282                 payload: vec![0],
283             },
284         )
285         .await;
286     }
287     let mut real_session_id = session_id;
288     loop {
289         match rx.recv().await {
290             Ok((msg, _index)) => {
291                 if msg.command == config::HdcCommand::KernelHandshake {
292                     if let Ok(id) = auth::get_new_session_id(&msg).await {
293                         if real_session_id != id {
294                             let (new_session_id, new_send_msg) = auth::handshake_init(msg.clone()).await?;
295                             let channel_id = new_send_msg.channel_id;
296 
297                             let wr = transfer::usb::UsbWriter { fd: bulkout_fd };
298                             transfer::UsbMap::start(new_session_id, wr).await;
299                             transfer::put(new_session_id, new_send_msg).await;
300 
301                             if auth::AuthStatusMap::get(new_session_id).await == auth::AuthStatus::Ok {
302                                 transfer::put(
303                                     new_session_id,
304                                     TaskMessage {
305                                         channel_id,
306                                         command: config::HdcCommand::KernelChannelClose,
307                                         payload: vec![0],
308                                     },
309                                 )
310                                 .await;
311                             }
312                             real_session_id = new_session_id;
313                         }
314                     }
315                 }
316                 ylong_runtime::spawn(async move {
317                     if let Err(e) = task::dispatch_task(msg, real_session_id).await {
318                         hdc::error!("dispatch task failed: {}", e.to_string());
319                     }
320                 });
321             }
322             Err(e) => {
323                 hdc::warn!("unpack task failed: {}", e.to_string());
324                 break;
325             }
326         }
327     }
328     Ok(())
329 }
330 
logger_init(log_level: LevelFilter)331 fn logger_init(log_level: LevelFilter) {
332     env_logger::Builder::new()
333         .format(|buf, record| {
334             let ts = humantime::format_rfc3339_millis(SystemTime::now()).to_string();
335             let level = &record.level().to_string()[..1];
336             let file = record.file().unwrap();
337             writeln!(
338                 buf,
339                 "{} {} {} {}:{} - {}",
340                 &ts[..10],
341                 &ts[11..23],
342                 level,
343                 file.split('/').last().unwrap(),
344                 record.line().unwrap(),
345                 record.args()
346             )
347         })
348         .filter(None, log_level)
349         .init();
350 }
351 
get_logger_lv() -> LevelFilter352 fn get_logger_lv() -> LevelFilter {
353     let lv = match std::env::var_os("HDCD_LOGLV") {
354         None => 0_usize,
355         // no need to prevent panic here
356         Some(lv) => lv.to_str().unwrap().parse::<usize>().unwrap(),
357     };
358     config::LOG_LEVEL_ORDER[lv]
359 }
360 
get_tcp_port() -> u16361 fn get_tcp_port() -> u16 {
362     let shell_command = format!("{} {}", config::SHELL_PARAM_GET, config::ENV_HOST_PORT,);
363     let result = utils::execute_cmd(shell_command);
364     let str_result = String::from_utf8(result);
365     if let Ok(str) = str_result {
366         println!("get_tcp_port from prop,value:{}", str);
367         let mut end = 0;
368         for i in 0..str.len() - 1 {
369             let c = str.as_bytes()[i];
370             if !c.is_ascii_digit() {
371                 end = i;
372                 break;
373             }
374         }
375         let str2 = str[0..end].to_string();
376         let number = str2.parse::<u16>();
377         if let Ok(num) = number {
378             println!("num:{}", num);
379             return num;
380         } else {
381             println!("num error");
382         }
383     }
384     config::DAEMON_PORT
385 }
386 
main()387 fn main() {
388     let args: Vec<String> = std::env::args().collect();
389     if args.len() == 2 && args[1] == "-v" {
390         println!("Ver 2.0.0a");
391         return;
392     }
393     logger_init(get_logger_lv());
394 
395     let _ = ylong_runtime::builder::RuntimeBuilder::new_multi_thread()
396         .worker_stack_size(16 * 1024 * 1024)
397         .worker_num(256)
398         .keep_alive_time(std::time::Duration::from_secs(10))
399         .build_global();
400 
401     need_drop_root_privileges();
402 
403     ylong_runtime::block_on(async {
404         let tcp_task = ylong_runtime::spawn(async {
405             if let Err(e) = tcp_daemon_start(get_tcp_port()).await {
406                 println!("[Fail]tcp daemon failed: {}", e);
407             }
408         });
409         let usb_task = ylong_runtime::spawn(async {
410             if let Err(e) = usb_daemon_start().await {
411                 println!("[Fail]usb daemon failed: {}", e);
412             }
413         });
414         let uart_task = ylong_runtime::spawn(async {
415             if let Err(e) = uart_daemon_start().await {
416                 println!("[Fail]uart daemon failed: {}", e);
417             }
418         });
419         let lock_value = Jdwp::get_instance();
420         let jdwp_server_task = ylong_runtime::spawn(async {
421             jdwp_daemon_start(lock_value).await;
422         });
423         let _ = tcp_task.await;
424         let _ = usb_task.await;
425         let _ = uart_task.await;
426         let _ = jdwp_server_task.await;
427     });
428 }
429