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 #![allow(missing_docs)]
17 
18 pub mod auth;
19 pub mod daemon_app;
20 pub mod daemon_unity;
21 pub mod mount;
22 pub mod shell;
23 pub mod task;
24 pub mod task_manager;
25 pub mod sys_para;
26 
27 #[cfg(feature = "emulator")]
28 pub mod bridge;
29 
30 use std::io::{self, ErrorKind};
31 use std::sync::Arc;
32 use std::ffi::c_int;
33 use crate::utils::{self, hdc_log::*};
34 
35 use crate::common::jdwp::Jdwp;
36 use crate::config;
37 use crate::config::TaskMessage;
38 #[cfg(feature = "emulator")]
39 use crate::daemon_lib::bridge;
40 use crate::transfer;
41 #[cfg(not(feature = "emulator"))]
42 use crate::transfer::base::Reader;
43 #[cfg(not(feature = "emulator"))]
44 use crate::transfer::uart::UartReader;
45 #[cfg(not(feature = "emulator"))]
46 use crate::transfer::uart_wrapper;
47 use crate::transfer::buffer::DiedSession;
48 
49 use crate::daemon_lib::sys_para::*;
50 use std::ffi::CString;
51 #[cfg(not(feature = "emulator"))]
52 use ylong_runtime::net::{TcpListener, TcpStream};
53 #[cfg(not(feature = "emulator"))]
54 use ylong_runtime::sync::mpsc;
55 
56 extern "C" {
57     #[cfg(not(feature = "emulator"))]
NeedDropRootPrivilegesnull58     fn NeedDropRootPrivileges() -> c_int;
59 }
60 
61 #[cfg(not(feature = "emulator"))]
need_drop_root_privilegesnull62 pub fn need_drop_root_privileges() {
63     crate::info!("need_drop_root_privileges");
64     unsafe {
65         NeedDropRootPrivileges();
66     }
67 }
68 
69 pub async fn handle_message(res: io::Result<TaskMessage>, session_id: u32) -> io::Result<()> {
70     match res {
71         Ok(msg) => {
72             utils::spawn(async move {
73                 if let Err(e) = task::dispatch_task(msg, session_id).await {
74                     crate::error!("dispatch tcp task failed: {}", e.to_string());
75                 }
76             });
77         }
78         Err(e) => {
79             crate::debug!("clear pty map: {}", session_id);
80             if e.kind() == ErrorKind::Other {
81                 crate::warn!("unpack task failed: {}", e.to_string());
82                 return Err(e);
83             }
84         }
85     };
86     Ok(())
87 }
88 
89 pub async fn jdwp_daemon_start(lock_value: Arc<Jdwp>) {
90     lock_value.init().await;
91 }
92 
93 #[cfg(feature = "emulator")]
94 pub async fn bridge_daemon_start() -> io::Result<()> {
95     crate::info!("bridge_daemon_start start...");
96     let ptr = bridge::init_bridge() as u64;
97     crate::info!("bridge_daemon_start ptr:{}", ptr);
98     let pipe_read_fd = bridge::start_listen(ptr);
99     crate::info!("bridge_daemon_start pipe_read_fd:{}", pipe_read_fd);
100     if pipe_read_fd < 0 {
101         crate::error!("daemon bridge listen fail.");
102         return Err(std::io::Error::new(
103             ErrorKind::Other,
104             "daemon bridge listen fail.",
105         ));
106     }
107     loop {
108         crate::info!("bridge_daemon_start loop...");
109         let client_fd_for_hdc_server = bridge::accept_server_socket_fd(ptr, pipe_read_fd);
110         if client_fd_for_hdc_server < 0 {
111             crate::error!("bridge_daemon_start accept client fd for hdc server fail...");
112             break;
113         }
114         let client_fd = bridge::init_client_fd(ptr, client_fd_for_hdc_server);
115         if client_fd < 0 {
116             crate::error!("bridge_daemon_start init client fd fail...");
117             break;
118         }
119         utils::spawn(bridge_handle_client(
120             ptr,
121             client_fd,
122             client_fd_for_hdc_server,
123         ));
124     }
125     bridge::stop(ptr);
126     Ok(())
127 }
128 
129 #[cfg(feature = "emulator")]
130 pub async fn bridge_handle_client(ptr: u64, fd: i32, client_fd: i32) -> io::Result<()> {
131     crate::info!("bridge_handle_client start...");
132     let rd = bridge::BridgeReader { ptr, fd };
133     let wr = bridge::BridgeWriter { ptr, fd };
134     let recv_msg = bridge::unpack_task_message(&rd).await?;
135     let (session_id, send_msg) = auth::handshake_init(recv_msg).await?;
136     let channel_id = send_msg.channel_id;
137     bridge::BridgeMap::start(session_id, wr).await;
138     transfer::put(session_id, send_msg).await;
139 
140     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
141         transfer::put(
142             session_id,
143             TaskMessage {
144                 channel_id,
145                 command: config::HdcCommand::KernelChannelClose,
146                 payload: vec![0],
147             },
148         )
149         .await;
150     }
151 
152     loop {
153         let ret = handle_message(transfer::tcp::unpack_task_message(&rd).await, session_id).await;
154         if ret.is_err() {
155             unsafe {
156                 libc::close(fd);
157                 libc::close(client_fd);
158             }
159             break;
160         }
161     }
162     Ok(())
163 }
164 
165 #[cfg(not(feature = "emulator"))]
166 pub async fn tcp_handle_client(stream: TcpStream) -> io::Result<()> {
167     let (mut rd, wr) = stream.into_split();
168     let msg = transfer::tcp::unpack_task_message(&mut rd).await?;
169     let session_id = auth::get_session_id_from_msg(&msg).await?;
170     crate::info!(
171         "tcp_handle_client session_id {session_id}, channel_id {}",
172         msg.channel_id
173     );
174     transfer::TcpMap::start(session_id, wr).await;
175     let ret = handle_message(Ok(msg), session_id).await;
176     if ret.is_err() {
177         transfer::TcpMap::end(session_id).await;
178         return ret;
179     }
180 
181     loop {
182         let result = handle_message(
183             transfer::tcp::unpack_task_message(&mut rd).await,
184             session_id,
185         )
186         .await;
187         if result.is_err() {
188             crate::warn!("tcp free_session, session_id:{}, result:{:?}", session_id, result);
189             task_manager::free_session(session_id).await;
190             return result;
191         }
192     }
193 }
194 
195 #[cfg(not(feature = "emulator"))]
196 pub async fn tcp_daemon_start(port: u16) -> io::Result<()> {
197     crate::info!("tcp_daemon_start port = {:#?}", port);
198     let saddr = format!("0.0.0.0:{}", port);
199     let listener = TcpListener::bind(saddr.clone()).await?;
200     let random_port = listener.local_addr()?.port();
201     crate::info!(
202         "daemon binds on saddr = {:#?}, port = {:#?}",
203         saddr,
204         random_port
205     );
206     if !set_dev_item(config::ENV_HOST_PORT, &random_port.to_string()) {
207         crate::error!("set tcp port: {} failed.", port);
208     }
209     loop {
210         let (stream, addr) = listener.accept().await?;
211         crate::info!("accepted client {addr}");
212         utils::spawn(async {
213             if let Err(e) = tcp_handle_client(stream).await {
214                 crate::error!("tcp_handle_client {e:?}");
215             }
216         });
217     }
218 }
219 
220 #[allow(unused)]
221 #[cfg(not(feature = "emulator"))]
222 pub async fn uart_daemon_start() -> io::Result<()> {
223     loop {
224         let fd = transfer::uart::uart_init()?;
225         if let Err(e) = uart_handle_client(fd).await {
226             crate::error!("uart_handle_client failed, {:?}", e);
227         }
228         transfer::uart::uart_close(fd);
229     }
230 }
231 
232 #[cfg(not(feature = "emulator"))]
233 pub async fn uart_handshake(
234     handshake_message: TaskMessage,
235     fd: i32,
236     rd: &UartReader,
237     package_index: u32,
238 ) -> io::Result<u32> {
239     let (session_id, send_msg) = auth::handshake_init(handshake_message).await?;
240     let channel_id = send_msg.channel_id;
241 
242     let wr = transfer::uart::UartWriter { fd };
243     transfer::start_uart(session_id, wr).await;
244     transfer::start_session(session_id).await;
245 
246     let Some(head) = rd.head.clone() else {
247         return Err(std::io::Error::new(
248             ErrorKind::Other,
249             "rd head clone failed",
250         ));
251     };
252     uart_wrapper::on_read_head(head).await;
253     transfer::wrap_put(session_id, send_msg, package_index, 0).await;
254 
255     if auth::AuthStatusMap::get(session_id).await == auth::AuthStatus::Ok {
256         transfer::put(
257             session_id,
258             TaskMessage {
259                 channel_id,
260                 command: config::HdcCommand::KernelChannelClose,
261                 payload: vec![0],
262             },
263         )
264         .await;
265     }
266     Ok(session_id)
267 }
268 
269 #[cfg(not(feature = "emulator"))]
270 pub async fn uart_handle_client(fd: i32) -> io::Result<()> {
271     let mut rd = transfer::uart::UartReader { fd, head: None };
272     let (packet_size, package_index, _session_id) = rd.check_protocol_head()?;
273     let (tx, mut rx) = mpsc::bounded_channel::<TaskMessage>(config::USB_QUEUE_LEN);
274     utils::spawn(async move {
275         let mut rd = transfer::uart::UartReader { fd, head: None };
276         if let Err(e) =
277             transfer::base::unpack_task_message_lock(&mut rd, packet_size, tx.clone()).await
278         {
279             crate::warn!("unpack task failed: {}, reopen fd...", e.to_string());
280         }
281     });
282     let session_id;
283     match rx.recv().await {
284         Ok(handshake_message) => {
285             let _ = rx.recv().await;
286             crate::info!("uart handshake_message:{:?}", handshake_message);
287             session_id = uart_handshake(handshake_message.clone(), fd, &rd, package_index).await?;
288         }
289         Err(e) => {
290             crate::info!("uart handshake error, {e:?}");
291             return Err(std::io::Error::new(
292                 ErrorKind::Other,
293                 format!("uart recv handshake error, {e:?}"),
294             ));
295         }
296     }
297 
298     uart_wrapper::stop_other_session(session_id).await;
299     let mut real_session_id = session_id;
300     loop {
301         let (packet_size, _package_index, _session_id) = rd.check_protocol_head()?;
302         let Some(head) = rd.head.clone() else {
303             return Err(std::io::Error::new(ErrorKind::Other, "rd head clone file"));
304         };
305         let package_index = head.package_index;
306         let session_id = head.session_id;
307         uart_wrapper::on_read_head(head).await;
308         if real_session_id != session_id {
309             crate::info!("real_session_id:{real_session_id}, session_id:{session_id}");
310             uart_wrapper::stop_other_session(session_id).await;
311         }
312         if packet_size == 0 {
313             continue;
314         }
315 
316         let (tx, mut rx) = mpsc::bounded_channel::<TaskMessage>(config::USB_QUEUE_LEN);
317         utils::spawn(async move {
318             let mut rd = transfer::uart::UartReader { fd, head: None };
319             if let Err(e) =
320                 transfer::base::unpack_task_message_lock(&mut rd, packet_size, tx.clone()).await
321             {
322                 crate::warn!("uart read uart taskmessage error:{:?}", e);
323             }
324         });
325 
326         loop {
327             match rx.recv().await {
328                 Ok(message) => {
329                     if message.command == config::HdcCommand::UartFinish {
330                         break;
331                     }
332 
333                     if message.command == config::HdcCommand::KernelHandshake {
334                         real_session_id =
335                             uart_handshake(message.clone(), fd, &rd, package_index).await?;
336                         crate::info!("real_session_id:{real_session_id:?}");
337                         continue;
338                     }
339                     let command = message.command;
340                     utils::spawn(async move {
341                         if let Err(e) = task::dispatch_task(message, real_session_id).await {
342                             log::error!("dispatch task({:?}) fail: {:?}", command, e);
343                         }
344                     });
345                 }
346                 Err(e) => {
347                     let error_msg = format!("uart recv error: {e:?}");
348                     crate::info!("{error_msg}");
349                     return Err(std::io::Error::new(ErrorKind::Other, error_msg));
350                 }
351             }
352         }
353     }
354 }
355 
356 #[cfg(not(feature = "emulator"))]
357 pub async fn usb_daemon_start() -> io::Result<()> {
358     loop {
359         let ret = transfer::usb::usb_init();
360         match ret {
361             Ok((config_fd, bulkin_fd, bulkout_fd)) => {
362                 let _ = usb_handle_client(config_fd, bulkin_fd, bulkout_fd).await;
363                 transfer::usb::usb_close(config_fd, bulkin_fd, bulkout_fd);
364             }
365             Err(e) => {
366                 crate::error!("usb init failure and restart hdcd error is {:?}", e);
367                 std::process::exit(0);
368             }
369         }
370     }
371 }
372 
373 #[cfg(not(feature = "emulator"))]
374 pub async fn usb_handle_client(_config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) -> io::Result<()> {
375     let _rd = transfer::usb::UsbReader { fd: bulkin_fd };
376     let mut rx = transfer::usb_start_recv(bulkin_fd, 0);
377     let mut cur_session_id = 0;
378     loop {
379         match rx.recv().await {
380             Ok((msg, _index, this_session_id)) => {
381                 if msg.command == config::HdcCommand::KernelHandshake {
382                     if let Ok(session_id_in_msg) = auth::get_session_id_from_msg(&msg).await {
383                         if session_id_in_msg != cur_session_id {
384                             task_manager::free_session(cur_session_id).await;
385                             crate::info!("free session(usb) over {:?} and new session is {}", cur_session_id, session_id_in_msg);
386                             let wr = transfer::usb::UsbWriter { fd: bulkout_fd };
387                             transfer::UsbMap::start(session_id_in_msg, wr).await;
388                             cur_session_id = session_id_in_msg;
389                         }
390                     }
391                 }
392                 if DiedSession::get(this_session_id).await {
393                     crate::error!("session is not connected, command:{:?}, this session:{this_session_id},
394                         current session:{cur_session_id}", msg.command);
395                     continue;
396                 }
397                 utils::spawn(async move {
398                     if let Err(e) = task::dispatch_task(msg, cur_session_id).await {
399                         crate::error!("dispatch task failed: {}", e.to_string());
400                     }
401                 });
402             }
403             Err(e) => {
404                 crate::warn!("unpack task failed: {}", e.to_string());
405                 break;
406             }
407         }
408     }
409     task_manager::free_session(cur_session_id).await;
410     Ok(())
411 }
412 
413 #[cfg(not(feature = "emulator"))]
get_tcp_portnull414 pub fn get_tcp_port() -> u16 {
415     let (ret, host_port) = get_dev_item(config::ENV_HOST_PORT, "_");
416     if !ret || host_port == "_" {
417         crate::error!(
418             "get host port failed, will use default port {}.",
419             config::DAEMON_PORT
420         );
421         return config::DAEMON_PORT;
422     }
423 
424     let str = host_port.trim();
425     crate::info!("get_tcp_port from prop, value:{}", str);
426     let mut end = str.len();
427     for i in 0..str.len() {
428         let c = str.as_bytes()[i];
429         if !c.is_ascii_digit() {
430             end = i;
431             break;
432         }
433     }
434     let str2 = str[0..end].to_string();
435     let number = str2.parse::<u16>();
436     if let Ok(num) = number {
437         crate::info!("get host port:{} success", num);
438         return num;
439     }
440 
441     crate::error!(
442         "convert host port failed, will use default port {}.",
443         config::DAEMON_PORT
444     );
445     config::DAEMON_PORT
446 }
447