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