1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci//! uds
16cc290419Sopenharmony_ci#![allow(missing_docs)]
17cc290419Sopenharmony_ci#![allow(clippy::missing_safety_doc)]
18cc290419Sopenharmony_ci#[cfg(not(feature = "host"))]
19cc290419Sopenharmony_ciuse crate::utils::hdc_log::*;
20cc290419Sopenharmony_ciuse libc::bind;
21cc290419Sopenharmony_ciuse libc::c_void;
22cc290419Sopenharmony_ciuse libc::{accept4, close, connect};
23cc290419Sopenharmony_ciuse libc::{c_char, listen, poll, recv, socket, MSG_NOSIGNAL};
24cc290419Sopenharmony_ciuse libc::{c_int, sa_family_t, sockaddr, sockaddr_un, socklen_t, AF_UNIX};
25cc290419Sopenharmony_ciuse libc::{eventfd, fcntl, pipe, read, send, socketpair, write, MSG_EOR};
26cc290419Sopenharmony_ciuse libc::{EFD_CLOEXEC, EFD_NONBLOCK, SOCK_CLOEXEC, SOCK_STREAM};
27cc290419Sopenharmony_ciuse libc::{POLLERR, POLLHUP, POLLNVAL, POLLRDHUP};
28cc290419Sopenharmony_ciuse std::io::{self, ErrorKind, Result};
29cc290419Sopenharmony_ciuse std::mem;
30cc290419Sopenharmony_ci
31cc290419Sopenharmony_ciconst LISTEN_BACKLOG: c_int = 10;
32cc290419Sopenharmony_ciconst MAX_CLIENT_FD_COUNT: usize = 256;
33cc290419Sopenharmony_ci
34cc290419Sopenharmony_ci#[derive(PartialEq, Debug, Clone)]
35cc290419Sopenharmony_cipub struct PollNode {
36cc290419Sopenharmony_ci    pub fd: i32,
37cc290419Sopenharmony_ci    pub events: i16,
38cc290419Sopenharmony_ci    pub revents: i16,
39cc290419Sopenharmony_ci    pub ppid: u32,
40cc290419Sopenharmony_ci    pub pkg_name: String,
41cc290419Sopenharmony_ci    pub is_debug: bool,
42cc290419Sopenharmony_ci}
43cc290419Sopenharmony_ci
44cc290419Sopenharmony_ciimpl PollNode {
45cc290419Sopenharmony_ci    pub fn new(fd: i32, ppid: u32, pkg_name: String, is_debug: bool) -> Self {
46cc290419Sopenharmony_ci        Self {
47cc290419Sopenharmony_ci            fd,
48cc290419Sopenharmony_ci            events: POLLNVAL | POLLRDHUP | POLLHUP | POLLERR,
49cc290419Sopenharmony_ci            revents: 0,
50cc290419Sopenharmony_ci            ppid,
51cc290419Sopenharmony_ci            pkg_name,
52cc290419Sopenharmony_ci            is_debug,
53cc290419Sopenharmony_ci        }
54cc290419Sopenharmony_ci    }
55cc290419Sopenharmony_ci}
56cc290419Sopenharmony_ci
57cc290419Sopenharmony_cifn name_index() -> socklen_t {
58cc290419Sopenharmony_ci    unsafe {
59cc290419Sopenharmony_ci        let total_size = mem::size_of::<sockaddr_un>();
60cc290419Sopenharmony_ci        let name_size = mem::size_of_val(&mem::zeroed::<sockaddr_un>().sun_path);
61cc290419Sopenharmony_ci        (total_size - name_size) as socklen_t
62cc290419Sopenharmony_ci    }
63cc290419Sopenharmony_ci}
64cc290419Sopenharmony_ci
65cc290419Sopenharmony_ci// const fn as_u8(slice: &[c_char]) -> &[u8] {
66cc290419Sopenharmony_ci//     unsafe { &*(slice as *const [c_char] as *const [u8]) }
67cc290419Sopenharmony_ci// }
68cc290419Sopenharmony_ci
69cc290419Sopenharmony_ciconst fn as_char(slice: &[u8]) -> &[c_char] {
70cc290419Sopenharmony_ci    unsafe { &*(slice as *const [u8] as *const [c_char]) }
71cc290419Sopenharmony_ci}
72cc290419Sopenharmony_ci
73cc290419Sopenharmony_cipub struct UdsAddr {
74cc290419Sopenharmony_ci    addr: sockaddr_un,
75cc290419Sopenharmony_ci    len: socklen_t,
76cc290419Sopenharmony_ci}
77cc290419Sopenharmony_ci
78cc290419Sopenharmony_ciimpl Default for UdsAddr {
79cc290419Sopenharmony_ci    fn default() -> Self {
80cc290419Sopenharmony_ci        let mut addr: sockaddr_un = unsafe { mem::zeroed() };
81cc290419Sopenharmony_ci        addr.sun_family = AF_UNIX as sa_family_t;
82cc290419Sopenharmony_ci        Self {
83cc290419Sopenharmony_ci            len: name_index(),
84cc290419Sopenharmony_ci            addr,
85cc290419Sopenharmony_ci        }
86cc290419Sopenharmony_ci    }
87cc290419Sopenharmony_ci}
88cc290419Sopenharmony_ci
89cc290419Sopenharmony_ciimpl UdsAddr {
90cc290419Sopenharmony_ci    pub fn parse_abstract(name: &[u8]) -> io::Result<Self> {
91cc290419Sopenharmony_ci        let mut addr = UdsAddr::default();
92cc290419Sopenharmony_ci        addr.addr.sun_path[1..1 + name.len()].copy_from_slice(as_char(name));
93cc290419Sopenharmony_ci        addr.len = name_index() + 1 + name.len() as socklen_t;
94cc290419Sopenharmony_ci        Ok(addr)
95cc290419Sopenharmony_ci    }
96cc290419Sopenharmony_ci
97cc290419Sopenharmony_ci    pub fn as_raw_general(&self) -> (&sockaddr, socklen_t) {
98cc290419Sopenharmony_ci        (
99cc290419Sopenharmony_ci            unsafe { &*(&self.addr as *const sockaddr_un as *const sockaddr) },
100cc290419Sopenharmony_ci            self.len,
101cc290419Sopenharmony_ci        )
102cc290419Sopenharmony_ci    }
103cc290419Sopenharmony_ci
104cc290419Sopenharmony_ci    pub unsafe fn as_raw_mut_general(&mut self) -> (&mut sockaddr, &mut socklen_t) {
105cc290419Sopenharmony_ci        (
106cc290419Sopenharmony_ci            &mut *(&mut self.addr as *mut sockaddr_un as *mut sockaddr),
107cc290419Sopenharmony_ci            &mut self.len,
108cc290419Sopenharmony_ci        )
109cc290419Sopenharmony_ci    }
110cc290419Sopenharmony_ci}
111cc290419Sopenharmony_ci
112cc290419Sopenharmony_cipub struct UdsServer {}
113cc290419Sopenharmony_ci
114cc290419Sopenharmony_ciimpl UdsServer {
115cc290419Sopenharmony_ci    pub fn wrap_socket(socket_type: c_int) -> i32 {
116cc290419Sopenharmony_ci        let flags = socket_type | SOCK_CLOEXEC;
117cc290419Sopenharmony_ci        unsafe { socket(AF_UNIX, flags, 0) }
118cc290419Sopenharmony_ci    }
119cc290419Sopenharmony_ci
120cc290419Sopenharmony_ci    pub fn wrap_bind(socket_fd: i32, addr: &UdsAddr) -> Result<()> {
121cc290419Sopenharmony_ci        unsafe {
122cc290419Sopenharmony_ci            let (addr_raw, len_raw) = addr.as_raw_general();
123cc290419Sopenharmony_ci            loop {
124cc290419Sopenharmony_ci                let ret = bind(socket_fd, addr_raw, len_raw);
125cc290419Sopenharmony_ci                if ret != -1 {
126cc290419Sopenharmony_ci                    break Ok(());
127cc290419Sopenharmony_ci                }
128cc290419Sopenharmony_ci                crate::error!("bind failed ret : {}", ret);
129cc290419Sopenharmony_ci                let err = io::Error::last_os_error();
130cc290419Sopenharmony_ci                if err.kind() != ErrorKind::Interrupted {
131cc290419Sopenharmony_ci                    break Err(err);
132cc290419Sopenharmony_ci                }
133cc290419Sopenharmony_ci            }
134cc290419Sopenharmony_ci        }
135cc290419Sopenharmony_ci    }
136cc290419Sopenharmony_ci
137cc290419Sopenharmony_ci    pub fn wrap_listen(socket_fd: i32) -> c_int {
138cc290419Sopenharmony_ci        unsafe { listen(socket_fd, LISTEN_BACKLOG) }
139cc290419Sopenharmony_ci    }
140cc290419Sopenharmony_ci
141cc290419Sopenharmony_ci    pub fn wrap_accept(socket_fd: i32) -> i32 {
142cc290419Sopenharmony_ci        let mut addr = UdsAddr::default();
143cc290419Sopenharmony_ci        let capacity = mem::size_of_val(&addr.addr) as socklen_t;
144cc290419Sopenharmony_ci        addr.len = capacity;
145cc290419Sopenharmony_ci        unsafe {
146cc290419Sopenharmony_ci            let (addr_ptr, len_ptr) = addr.as_raw_mut_general();
147cc290419Sopenharmony_ci            accept4(socket_fd, addr_ptr, len_ptr, SOCK_CLOEXEC)
148cc290419Sopenharmony_ci        }
149cc290419Sopenharmony_ci    }
150cc290419Sopenharmony_ci
151cc290419Sopenharmony_ci    pub fn wrap_recv(socket_fd: i32, buffer: &mut [u8]) -> isize {
152cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *mut c_void;
153cc290419Sopenharmony_ci        unsafe { recv(socket_fd, ptr, buffer.len(), MSG_NOSIGNAL) }
154cc290419Sopenharmony_ci    }
155cc290419Sopenharmony_ci
156cc290419Sopenharmony_ci    pub fn wrap_read(socket_fd: i32, buffer: &mut [u8]) -> isize {
157cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *mut c_void;
158cc290419Sopenharmony_ci        unsafe { read(socket_fd, ptr, buffer.len()) }
159cc290419Sopenharmony_ci    }
160cc290419Sopenharmony_ci
161cc290419Sopenharmony_ci    pub fn wrap_write(socket_fd: i32, buffer: &[u8]) -> isize {
162cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *const c_void;
163cc290419Sopenharmony_ci        unsafe { write(socket_fd, ptr, buffer.len()) }
164cc290419Sopenharmony_ci    }
165cc290419Sopenharmony_ci
166cc290419Sopenharmony_ci    pub fn wrap_event_fd() -> i32 {
167cc290419Sopenharmony_ci        unsafe { eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK) }
168cc290419Sopenharmony_ci    }
169cc290419Sopenharmony_ci
170cc290419Sopenharmony_ci    pub fn wrap_write_fd(fd: i32) {
171cc290419Sopenharmony_ci        unsafe {
172cc290419Sopenharmony_ci            let buf = [1u64; 1];
173cc290419Sopenharmony_ci            let ret = write(fd, buf.as_ptr() as *const c_void, mem::size_of_val(&buf));
174cc290419Sopenharmony_ci            crate::info!("uds wrap_write fd, fd:{}, ret:{}", fd, ret);
175cc290419Sopenharmony_ci        }
176cc290419Sopenharmony_ci    }
177cc290419Sopenharmony_ci
178cc290419Sopenharmony_ci    pub fn wrap_read_fd(fd: i32) {
179cc290419Sopenharmony_ci        unsafe {
180cc290419Sopenharmony_ci            let buf = [1u64; 1];
181cc290419Sopenharmony_ci            read(fd, buf.as_ptr() as *mut c_void, mem::size_of_val(&buf));
182cc290419Sopenharmony_ci        }
183cc290419Sopenharmony_ci    }
184cc290419Sopenharmony_ci
185cc290419Sopenharmony_ci    pub fn wrap_poll(fds: &mut [PollNode], size: u32, timeout: i32) -> i32 {
186cc290419Sopenharmony_ci        let init_value = unsafe { mem::zeroed() };
187cc290419Sopenharmony_ci        let pollfds: &mut [libc::pollfd; MAX_CLIENT_FD_COUNT] =
188cc290419Sopenharmony_ci            &mut [init_value; MAX_CLIENT_FD_COUNT];
189cc290419Sopenharmony_ci        for (index, node) in fds.iter_mut().enumerate() {
190cc290419Sopenharmony_ci            if !(0..MAX_CLIENT_FD_COUNT).contains(&index) {
191cc290419Sopenharmony_ci                continue;
192cc290419Sopenharmony_ci            }
193cc290419Sopenharmony_ci            pollfds[index].fd = node.fd;
194cc290419Sopenharmony_ci            pollfds[index].events = node.events;
195cc290419Sopenharmony_ci            pollfds[index].revents = node.revents;
196cc290419Sopenharmony_ci        }
197cc290419Sopenharmony_ci        unsafe {
198cc290419Sopenharmony_ci            let ret = poll(pollfds.as_mut_ptr(), size as libc::nfds_t, timeout);
199cc290419Sopenharmony_ci            crate::info!("uds wrap_poll, poll ret:{}", ret);
200cc290419Sopenharmony_ci            if ret == -1 {
201cc290419Sopenharmony_ci                ret
202cc290419Sopenharmony_ci            } else {
203cc290419Sopenharmony_ci                for i in 0..size as usize {
204cc290419Sopenharmony_ci                    if i >= fds.len() {
205cc290419Sopenharmony_ci                        break;
206cc290419Sopenharmony_ci                    }
207cc290419Sopenharmony_ci                    fds[i].revents = pollfds[i].revents;
208cc290419Sopenharmony_ci                    fds[i].events = pollfds[i].events;
209cc290419Sopenharmony_ci                }
210cc290419Sopenharmony_ci                0
211cc290419Sopenharmony_ci            }
212cc290419Sopenharmony_ci        }
213cc290419Sopenharmony_ci    }
214cc290419Sopenharmony_ci
215cc290419Sopenharmony_ci    #[allow(unused)]
216cc290419Sopenharmony_ci    pub fn wrap_send(socket_fd: i32, buffer: &[u8]) -> isize {
217cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *const c_void;
218cc290419Sopenharmony_ci        let flags = MSG_NOSIGNAL | MSG_EOR;
219cc290419Sopenharmony_ci        unsafe { send(socket_fd, ptr, buffer.len(), flags) }
220cc290419Sopenharmony_ci    }
221cc290419Sopenharmony_ci
222cc290419Sopenharmony_ci    #[allow(unused)]
223cc290419Sopenharmony_ci    pub fn wrap_close(socket_fd: i32) {
224cc290419Sopenharmony_ci        unsafe { close(socket_fd) };
225cc290419Sopenharmony_ci    }
226cc290419Sopenharmony_ci
227cc290419Sopenharmony_ci    #[allow(unused)]
228cc290419Sopenharmony_ci    pub fn wrap_socketpair(socket_type: c_int) -> Result<(i32, i32)> {
229cc290419Sopenharmony_ci        let flags = socket_type | SOCK_CLOEXEC;
230cc290419Sopenharmony_ci        let mut fd_buf = [-1; 2];
231cc290419Sopenharmony_ci        unsafe {
232cc290419Sopenharmony_ci            socketpair(AF_UNIX, flags, 0, fd_buf[..].as_mut_ptr());
233cc290419Sopenharmony_ci            fcntl(fd_buf[1], 100, 20);
234cc290419Sopenharmony_ci        }
235cc290419Sopenharmony_ci        Ok((fd_buf[0], fd_buf[1]))
236cc290419Sopenharmony_ci    }
237cc290419Sopenharmony_ci
238cc290419Sopenharmony_ci    #[allow(unused)]
239cc290419Sopenharmony_ci    pub fn wrap_pipe() -> Result<(i32, i32)> {
240cc290419Sopenharmony_ci        let mut fd_buf = [-1; 2];
241cc290419Sopenharmony_ci        unsafe {
242cc290419Sopenharmony_ci            crate::debug!("pipe() begin...");
243cc290419Sopenharmony_ci            let ret = pipe(fd_buf[..].as_mut_ptr());
244cc290419Sopenharmony_ci            crate::debug!("pipe() ret:{}", ret);
245cc290419Sopenharmony_ci            if ret >= 0 {
246cc290419Sopenharmony_ci                fcntl(fd_buf[1], 100, 20);
247cc290419Sopenharmony_ci            }
248cc290419Sopenharmony_ci        }
249cc290419Sopenharmony_ci        Ok((fd_buf[0], fd_buf[1]))
250cc290419Sopenharmony_ci    }
251cc290419Sopenharmony_ci}
252cc290419Sopenharmony_ci
253cc290419Sopenharmony_cipub struct UdsClient {}
254cc290419Sopenharmony_ci
255cc290419Sopenharmony_ciimpl UdsClient {
256cc290419Sopenharmony_ci    pub fn wrap_socket(af: i32) -> i32 {
257cc290419Sopenharmony_ci        let flags = SOCK_STREAM | SOCK_CLOEXEC;
258cc290419Sopenharmony_ci        unsafe { socket(af, flags, 0) }
259cc290419Sopenharmony_ci    }
260cc290419Sopenharmony_ci
261cc290419Sopenharmony_ci    pub fn wrap_bind(socket_fd: i32, addr: &UdsAddr) -> Result<()> {
262cc290419Sopenharmony_ci        unsafe {
263cc290419Sopenharmony_ci            let (addr_raw, len_raw) = addr.as_raw_general();
264cc290419Sopenharmony_ci            loop {
265cc290419Sopenharmony_ci                let ret = bind(socket_fd, addr_raw, len_raw);
266cc290419Sopenharmony_ci                crate::debug!("bind ret : {}", ret);
267cc290419Sopenharmony_ci                if ret != -1 {
268cc290419Sopenharmony_ci                    break Ok(());
269cc290419Sopenharmony_ci                }
270cc290419Sopenharmony_ci                let err = io::Error::last_os_error();
271cc290419Sopenharmony_ci                if err.kind() != ErrorKind::Interrupted {
272cc290419Sopenharmony_ci                    break Err(err);
273cc290419Sopenharmony_ci                }
274cc290419Sopenharmony_ci            }
275cc290419Sopenharmony_ci        }
276cc290419Sopenharmony_ci    }
277cc290419Sopenharmony_ci
278cc290419Sopenharmony_ci    pub fn wrap_listen(socket_fd: i32) -> c_int {
279cc290419Sopenharmony_ci        unsafe { listen(socket_fd, LISTEN_BACKLOG) }
280cc290419Sopenharmony_ci    }
281cc290419Sopenharmony_ci
282cc290419Sopenharmony_ci    pub fn wrap_connect(socket_fd: i32, addr: &UdsAddr) -> Result<()> {
283cc290419Sopenharmony_ci        unsafe {
284cc290419Sopenharmony_ci            let (addr_raw, len_raw) = addr.as_raw_general();
285cc290419Sopenharmony_ci            crate::debug!("wrap_connect:len_raw: {:#?}", len_raw);
286cc290419Sopenharmony_ci            crate::debug!("wrap_connect:addr_raw: {:#?}", addr_raw.sa_data);
287cc290419Sopenharmony_ci            loop {
288cc290419Sopenharmony_ci                let ret = connect(socket_fd, addr_raw, len_raw);
289cc290419Sopenharmony_ci                crate::debug!("connect ret ++++++---->: {}", ret);
290cc290419Sopenharmony_ci                if ret != -1 {
291cc290419Sopenharmony_ci                    break Ok(());
292cc290419Sopenharmony_ci                }
293cc290419Sopenharmony_ci                let err = io::Error::last_os_error();
294cc290419Sopenharmony_ci                if err.kind() != ErrorKind::Interrupted {
295cc290419Sopenharmony_ci                    break Err(err);
296cc290419Sopenharmony_ci                }
297cc290419Sopenharmony_ci            }
298cc290419Sopenharmony_ci        }
299cc290419Sopenharmony_ci    }
300cc290419Sopenharmony_ci
301cc290419Sopenharmony_ci    pub fn wrap_recv(socket_fd: i32, buffer: &mut [u8]) -> isize {
302cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *mut c_void;
303cc290419Sopenharmony_ci        unsafe { recv(socket_fd, ptr, buffer.len(), MSG_NOSIGNAL) }
304cc290419Sopenharmony_ci    }
305cc290419Sopenharmony_ci
306cc290419Sopenharmony_ci    pub fn wrap_read(socket_fd: i32, buffer: &mut [u8]) -> isize {
307cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *mut c_void;
308cc290419Sopenharmony_ci        unsafe { read(socket_fd, ptr, buffer.len()) }
309cc290419Sopenharmony_ci    }
310cc290419Sopenharmony_ci
311cc290419Sopenharmony_ci    pub fn wrap_write(socket_fd: i32, buffer: &[u8]) -> isize {
312cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *const c_void;
313cc290419Sopenharmony_ci        unsafe { write(socket_fd, ptr, buffer.len()) }
314cc290419Sopenharmony_ci    }
315cc290419Sopenharmony_ci
316cc290419Sopenharmony_ci    pub fn wrap_send(socket_fd: i32, buffer: &[u8]) -> isize {
317cc290419Sopenharmony_ci        let ptr = buffer.as_ptr() as *const c_void;
318cc290419Sopenharmony_ci        let flags = MSG_NOSIGNAL | MSG_EOR;
319cc290419Sopenharmony_ci        unsafe { send(socket_fd, ptr, buffer.len(), flags) }
320cc290419Sopenharmony_ci    }
321cc290419Sopenharmony_ci}
322