From 61b1dc3b7ebba31bc2a002926a7113dfad541a4b Mon Sep 17 00:00:00 2001 From: baiwei Date: Fri, 21 Apr 2023 08:19:18 +0000 Subject: [PATCH 1/3] =?UTF-8?q?rust=E9=87=8D=E6=9E=84socket=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E8=AE=BE=E6=96=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: baiwei Change-Id: I060ba4fd0bfd78a36704dc9cd264114e26d9d4ac --- bundle.json | 3 +- rust/utils/socket_ipc_rust_ffi/BUILD.gn | 57 ++ rust/utils/socket_ipc_rust_ffi/src/binding.rs | 35 ++ rust/utils/socket_ipc_rust_ffi/src/error.rs | 121 +++++ rust/utils/socket_ipc_rust_ffi/src/lib.rs | 34 ++ .../socket_ipc_rust_ffi/src/net_packet.rs | 165 ++++++ .../socket_ipc_rust_ffi/src/net_packet/ffi.rs | 81 +++ .../socket_ipc_rust_ffi/src/stream_buffer.rs | 507 ++++++++++++++++++ .../src/stream_buffer/ffi.rs | 290 ++++++++++ .../socket_ipc_rust_ffi/src/stream_session.rs | 163 ++++++ .../src/stream_session/ffi.rs | 139 +++++ .../socket_ipc_rust_ffi/src/stream_socket.rs | 203 +++++++ .../src/stream_socket/ffi.rs | 179 +++++++ rust/utils/socket_ipc_rust_ffi/test/main.rs | 135 +++++ sensor.gni | 26 + services/sensor/BUILD.gn | 7 + services/sensor/src/sensor_power_policy.cpp | 4 + utils/ipc/BUILD.gn | 7 + utils/ipc/include/rust_binding.h | 98 ++++ utils/ipc/include/stream_buffer.h | 30 +- utils/ipc/include/stream_session.h | 8 + utils/ipc/include/stream_socket.h | 13 +- utils/ipc/src/circle_stream_buffer.cpp | 124 +++-- utils/ipc/src/net_packet.cpp | 147 ++--- utils/ipc/src/stream_buffer.cpp | 102 ++-- utils/ipc/src/stream_session.cpp | 65 ++- utils/ipc/src/stream_socket.cpp | 93 +++- 27 files changed, 2654 insertions(+), 182 deletions(-) create mode 100644 rust/utils/socket_ipc_rust_ffi/BUILD.gn create mode 100644 rust/utils/socket_ipc_rust_ffi/src/binding.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/error.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/lib.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/net_packet.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/stream_session.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs create mode 100644 rust/utils/socket_ipc_rust_ffi/test/main.rs create mode 100644 sensor.gni create mode 100644 utils/ipc/include/rust_binding.h diff --git a/bundle.json b/bundle.json index 013898ca..0a269b64 100644 --- a/bundle.json +++ b/bundle.json @@ -62,7 +62,8 @@ "test": [ "//base/sensors/sensor/interfaces/plugin/test/unittest:unittest", "//base/sensors/sensor/interfaces/native/test/fuzztest:fuzztest", - "//base/sensors/sensor/interfaces/native/test:unittest" + "//base/sensors/sensor/interfaces/native/test:unittest", + "//base/sensors/sensor/rust/utils/socket_ipc_rust_ffi:unittest" ] } } diff --git a/rust/utils/socket_ipc_rust_ffi/BUILD.gn b/rust/utils/socket_ipc_rust_ffi/BUILD.gn new file mode 100644 index 00000000..0d56aefa --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/BUILD.gn @@ -0,0 +1,57 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_rust_shared_ffi("sensor_rust_util_ffi") { + sources = [ "src/lib.rs" ] + + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:hilog_rust", + "hiviewdfx_hilog_native:libhilog", + ] + + crate_name = "sensor_rust_util_ffi" + crate_type = "cdylib" + install_images = [ system_base_dir ] + + part_name = "sensor" + subsystem_name = "sensors" +} + +ohos_rust_shared_library("sensor_rust_util") { + sources = [ "src/lib.rs" ] + + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:hilog_rust", + "hiviewdfx_hilog_native:libhilog", + ] + + crate_name = "sensor_rust_util" + crate_type = "dylib" + install_images = [ system_base_dir ] + + part_name = "sensor" + subsystem_name = "sensors" +} + +ohos_executable("test_sensor_pkt") { + sources = [ "test/main.rs" ] + deps = [ ":sensor_rust_util" ] +} + +group("unittest") { + deps = [ ":test_sensor_pkt" ] +} diff --git a/rust/utils/socket_ipc_rust_ffi/src/binding.rs b/rust/utils/socket_ipc_rust_ffi/src/binding.rs new file mode 100644 index 00000000..a163aa3a --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/binding.rs @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + // C interface for socket core object +use libc::c_void; +/// C StreamServer struct pointer +#[repr(C)] +pub struct CStreamServer { + _private: [u8; 0], +} +/// C Client struct pointer +#[repr(C)] +pub struct CClient { + _private: [u8; 0], +} + +extern "C" { + /// extern safe C function + pub fn memcpy_s(dest: *mut c_void, dest_size: libc::size_t, src: *const c_void, count: libc::size_t) -> i32; + /// extern safe C function + pub fn memset_s(dest: *mut c_void, dest_size: libc::size_t, ch: libc::c_int, count: libc::size_t) -> i32; +} + diff --git a/rust/utils/socket_ipc_rust_ffi/src/error.rs b/rust/utils/socket_ipc_rust_ffi/src/error.rs new file mode 100644 index 00000000..192c5bf7 --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/error.rs @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +pub enum SocketStatusCode { + Ok = 0, + Fail = -1, + FdFail = -2, + EpollFdFail = -3, + EpollCreateFail = -4, + EpollCtlFail = -5, + EpollWaitFail = -6, + EpollCloseFail = -7, + SocketCloseFail = -8, +} + +pub enum BufferStatusCode { + Ok = 0, + Fail = -1, + ResetFail = -2, + CleanFail = -3, + UnreadSizeFail = -4, + IsEmptyFail = -5, + WriteStreamBufferFail = -6, + ReadStreamBufferFail = -7, + CheckRWErrorFail = -8, + CopyDataToBeginFail = -9, + ReadCharUsizeFail = -10, + ReadServerPacketsFail = -11, + ReadClientPacketsFail = -12, + SizeFail = -13, +} + +pub enum SessionStatusCode { + Ok = 0, + Fail = -1, + UidFail = -2, + PidFail = -3, + ModuleTypeFail = -4, + FdFail = -5, + SetTokenTypeFail = -6, + TokenTypeFail = -7, + CloseFail = -8, +} +pub enum NetPacketStatusCode { + Ok = 0, + Fail = -1, + PacketLengthFail = -2, +} + +impl From for i32 { + fn from(code: SocketStatusCode) -> i32 { + match code { + SocketStatusCode::Ok => 0, + SocketStatusCode::FdFail => -2, + SocketStatusCode::EpollFdFail => -3, + SocketStatusCode::EpollCreateFail => -4, + SocketStatusCode::EpollCtlFail => -5, + SocketStatusCode::EpollWaitFail => -6, + SocketStatusCode::EpollCloseFail => -7, + SocketStatusCode::SocketCloseFail => -8, + _ => -1, + } + } +} +impl From for i32 { + fn from(code: BufferStatusCode) -> i32 { + match code { + BufferStatusCode::Ok => 0, + BufferStatusCode::ResetFail => -2, + BufferStatusCode::CleanFail => -3, + BufferStatusCode::UnreadSizeFail => -4, + BufferStatusCode::IsEmptyFail => -5, + BufferStatusCode::WriteStreamBufferFail => -6, + BufferStatusCode::ReadStreamBufferFail => -7, + BufferStatusCode::CheckRWErrorFail => -8, + BufferStatusCode::CopyDataToBeginFail => -9, + BufferStatusCode::ReadCharUsizeFail => -10, + BufferStatusCode::ReadServerPacketsFail => -11, + BufferStatusCode::ReadClientPacketsFail => -12, + BufferStatusCode::SizeFail => -13, + _ => -1, + } + } +} + +impl From for i32 { + fn from(code: SessionStatusCode) -> i32 { + match code { + SessionStatusCode::Ok => 0, + SessionStatusCode::UidFail => -2, + SessionStatusCode::PidFail => -3, + SessionStatusCode::ModuleTypeFail => -4, + SessionStatusCode::FdFail => -5, + SessionStatusCode::SetTokenTypeFail => -6, + SessionStatusCode::TokenTypeFail => -7, + SessionStatusCode::CloseFail => -8, + _ => -1, + } + } +} +impl From for i32 { + fn from(code: NetPacketStatusCode) -> i32 { + match code { + NetPacketStatusCode::Ok => 0, + NetPacketStatusCode::PacketLengthFail => -2, + _ => -1, + } + } +} \ No newline at end of file diff --git a/rust/utils/socket_ipc_rust_ffi/src/lib.rs b/rust/utils/socket_ipc_rust_ffi/src/lib.rs new file mode 100644 index 00000000..f0c1b9ff --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/lib.rs @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! Safe Rust interface to OHOS msdp +#![feature(rustc_private)] +#![allow(dead_code)] + +extern crate libc; +/// mod stream socket +pub mod stream_socket; +/// mod stream buffer +pub mod stream_buffer; +/// mod stream session +pub mod stream_session; +/// mod net packet +pub mod net_packet; +/// mod binding for binding extern C interface +pub mod binding; +mod error; +/// annotation +pub type Result = std::result::Result; + diff --git a/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs b/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs new file mode 100644 index 00000000..5fadf1fd --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// C++ call function +pub mod ffi; +use std::ffi::{CString, c_char}; +use hilog_rust::{hilog, error, HiLogLabel, LogType}; +use std::mem::size_of; +use crate::stream_buffer::StreamBuffer; +const STREAM_BUF_WRITE_FAIL: i32 = 2; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "NetPacket" +}; + +/// struct PackHead +#[repr(packed(1))] +#[repr(C)] +pub struct PackHead { + /// NetPacket type + pub id_msg: MessageId, + /// SufferBuffer size + pub size: i32, +} + +/// NetPacket type +#[derive(Copy, Clone)] +#[repr(C)] +pub enum MessageId { + /// + Invalid = 0, + /// + Device, + /// + DeviceIds, + /// + DeviceSupportKeys, + /// + AddDeviceListener, + /// + DeviceKeyboardType, + /// + DisplayInfo, + /// + NoticeAnr, + /// + MarkProcess, + /// + OnSubscribeKey, + /// + OnKeyEvent, + /// + OnPointerEvent, + /// + ReportKeyEvent, + /// + ReportPointerEvent, + /// + OnDeviceAdded, + /// + OnDeviceRemoved, + /// + CoordinationAddListener, + /// + CoordinationMessage, + /// + CoordinationGetState, + + /// + DragNotifyResult, + /// + DragStateListener, +} + +/// struct NetPacket +#[derive(Copy, Clone)] +#[repr(C)] +pub struct NetPacket { + /// NetPacket head + pub msg_id: MessageId, + /// NetPacket streambuffer + pub stream_buffer: StreamBuffer, +} + +impl Default for NetPacket { + fn default() -> Self { + Self { + msg_id: MessageId::Invalid, + stream_buffer: Default::default(), + } + } +} + +impl NetPacket { + /// get refenrance from pointer + /// + ///# Safety + /// + /// object pointer is valid + pub unsafe fn as_ref<'a>(object: *const Self) -> Option<&'a Self>{ + object.as_ref() + } + /// get mut refenrance from pointer + /// + ///# Safety + /// + /// object pointer is valid + pub unsafe fn as_mut<'a>(object: *mut Self) -> Option<&'a mut Self>{ + object.as_mut() + } + /// write + pub fn write(&mut self, data: T) { + let data: *const c_char = &data as *const T as *const c_char; + let size = size_of::(); + self.stream_buffer.write_char_usize(data, size); + } + /// read + pub fn read(&mut self, data: &mut T) { + let data: *mut c_char = data as *mut T as *mut c_char; + let size = size_of::(); + self.stream_buffer.read_char_usize(data, size); + } + /// get_size + pub fn size(&self) -> usize { + self.stream_buffer.size() + } + /// get_packet_length + pub fn get_packet_length(&self) -> i32 { + size_of::() as i32 + self.stream_buffer.w_pos + } + /// get_data + pub fn get_data(&self) -> *const c_char { + self.stream_buffer.data() + } + /// get_msg_id + pub fn get_msg_id(&self) -> MessageId { + self.msg_id + } + /// make_data + pub fn make_data(&self, buf: &mut StreamBuffer) { + let head = PackHead { + id_msg: self.msg_id, + size: self.stream_buffer.w_pos, + }; + buf.write(head); + if self.stream_buffer.w_pos > 0 && !buf.write_char_usize(&self.stream_buffer.sz_buff[0] as *const c_char, + self.stream_buffer.w_pos as usize) { + error!(LOG_LABEL, "Write data to stream failed, errCode:{}", STREAM_BUF_WRITE_FAIL); + } + } +} + diff --git a/rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs new file mode 100644 index 00000000..b896fd5e --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::*; +use hilog_rust::{info, hilog, HiLogLabel, LogType}; +use std::ffi::CString; +use crate::error::NetPacketStatusCode; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "net_packet_ffi" +}; + +/// Get size +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_size(object: *const NetPacket) -> usize { + info!(LOG_LABEL, "enter get_size"); + if let Some(obj) = NetPacket::as_ref(object) { + obj.size() + } else { + 0 + } +} +/// Get packet length +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_packet_length(object: *const NetPacket) -> i32 { + info!(LOG_LABEL, "enter get_packet_length"); + if let Some(obj) = NetPacket::as_ref(object) { + obj.get_packet_length() + } else { + NetPacketStatusCode::PacketLengthFail.into() + } +} +/// Get data +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_data(object: *const NetPacket) -> *const c_char { + info!(LOG_LABEL, "enter get_data"); + if let Some(obj) = NetPacket::as_ref(object) { + obj.get_data() + } else { + std::ptr::null() + } +} +/// Get msg_id +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_msg_id(object: *const NetPacket) -> MessageId { + info!(LOG_LABEL, "enter get_msg_id"); + if let Some(obj) = NetPacket::as_ref(object) { + obj.get_msg_id() + } else { + MessageId::Invalid + } +} diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs new file mode 100644 index 00000000..28d63e78 --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// provide C interface to C++ for calling +pub mod ffi; +use hilog_rust::{info, error, hilog, debug, HiLogLabel, LogType}; +use std::ffi::{CString, c_char}; +use crate::binding; +use std::mem::size_of; +use crate::binding::CStreamServer; +use crate::binding::CClient; +use crate::net_packet::NetPacket; +use crate::net_packet::PackHead; +type ErrorStatus = crate::stream_buffer::ErrStatus; +/// function pointer alias +pub type ServerPacketCallBackFun = unsafe extern "C" fn ( + stream_server: *const CStreamServer, + fd: i32, + pkt: *const NetPacket, +); +/// function pointer alias +pub type ClientPacketCallBackFun = unsafe extern "C" fn ( + client: *const CClient, + pkt: *const NetPacket, +); +/// function pointer alias +pub type ReadPacketCallBackFun = unsafe fn ( + pkt: *mut NetPacket, +); +const ONCE_PROCESS_NETPACKET_LIMIT: i32 = 100; +const MAX_STREAM_BUF_SIZE: usize = 256; +/// max buffer size of packet +pub const MAX_PACKET_BUF_SIZE: usize = 256; +const PARAM_INPUT_INVALID: i32 = 5; +const MEM_OUT_OF_BOUNDS: i32 = 3; +const MEMCPY_SEC_FUN_FAIL: i32 = 4; +const STREAM_BUF_READ_FAIL: i32 = 1; +const MAX_VECTOR_SIZE: i32 = 10; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "StreamBuffer" +}; + +/// enum errstatus +#[derive(Copy, Clone, PartialEq)] +#[repr(C)] +pub enum ErrStatus { + /// status ok + Ok = 0, + /// readerror + Read = 1, + /// writeerror + Write = 2, +} + +/// struct streambuffer +#[derive(Copy, Clone)] +#[repr(C)] +pub struct StreamBuffer { + /// error status of read or write + pub rw_error_status: ErrorStatus, + /// read count + pub r_count: i32, + /// write count + pub w_count: i32, + /// read position + pub r_pos: i32, + /// write position + pub w_pos: i32, + /// buffer of read or write + pub sz_buff: [c_char; MAX_STREAM_BUF_SIZE + 1], +} + +impl Default for StreamBuffer { + fn default() -> Self { + Self { + rw_error_status: ErrorStatus::Ok, + r_count: 0, + w_count: 0, + r_pos: 0, + w_pos: 0, + sz_buff: [0; MAX_STREAM_BUF_SIZE + 1], + } + } +} + + +impl StreamBuffer { + /// return const referance of self + /// + /// # Safety + /// + /// Makesure object is null pointer + unsafe fn as_ref<'a>(object: *const Self) -> Option<&'a Self>{ + object.as_ref() + } + /// return mutable referance of self + /// + /// # Safety + /// + /// Makesure object is null pointer + unsafe fn as_mut<'a>(object: *mut Self) -> Option<&'a mut Self>{ + object.as_mut() + } + + /// write + pub fn write(&mut self, data: T) { + let data: *const c_char = &data as *const T as *const c_char; + let size = size_of::(); + self.write_char_usize(data, size); + } + + fn reset(&mut self) { + self.r_pos = 0; + self.w_pos = 0; + self.r_count = 0; + self.w_count = 0; + self.rw_error_status = ErrorStatus::Ok; + } + + fn clean(&mut self) { + self.reset(); + let size = MAX_STREAM_BUF_SIZE + 1; + let reference = &(self.sz_buff); + let pointer = reference as *const c_char; + unsafe { + let ret = binding::memset_s(pointer as *mut libc::c_void, size, 0, size); + if ret != 0 { + error!(LOG_LABEL, "Call memset_s fail"); + } + } + } + + fn seek_read_pos(&mut self, n: i32) -> bool { + let pos: i32 = self.r_pos + n; + if pos < 0 || pos > self.w_pos { + error!(LOG_LABEL, "The position in the calculation is not as expected. pos:{} [0, {}]", + pos, self.w_pos); + return false; + } + self.r_pos = pos; + true + } + /// write buffer + pub fn write_buf(&self) -> *const c_char { + info!(LOG_LABEL, "enter write_buf"); + &self.sz_buff[self.w_pos as usize] as *const c_char + } + /// unread size + pub fn unread_size(&self) -> i32 { + if self.w_pos <= self.r_pos { + 0 + } else { + self.w_pos - self.r_pos + } + } + + fn is_empty(&self) -> bool { + self.r_pos == self.w_pos + } + + fn write_streambuffer(&mut self, buf: &Self) -> bool { + self.write_char_usize(buf.data(), buf.size()) + } + fn read_streambuffer(&self, buf: &mut Self) -> bool { + buf.write_char_usize(self.data(), self.size()) + } + /// data function + pub fn data(&self) -> *const c_char { + &(self.sz_buff[0]) as *const c_char + } + /// size function + pub fn size(&self) -> usize { + self.w_pos as usize + } + /// check error status of read or write + pub fn chk_rwerror(&self) -> bool { + self.rw_error_status != ErrorStatus::Ok + } + fn get_available_buf_size(&self) -> i32 { + if self.w_pos >= MAX_STREAM_BUF_SIZE as i32 { + 0 + } else { + MAX_STREAM_BUF_SIZE as i32 - self.w_pos + } + } + fn get_error_status_remark(&self) -> *const c_char { + let s = match self.rw_error_status { + ErrorStatus::Ok => "OK\0", + ErrorStatus::Read => "READ_ERROR\0", + ErrorStatus::Write => "WRITE_ERROR\0", + }; + error!(LOG_LABEL, "rw_error_status={}", s); + s.as_ptr() + } + fn read_buf(&self) -> *const c_char { + &(self.sz_buff[self.r_pos as usize]) as *const c_char + } + /// write buffer + pub fn write_char_usize(&mut self, buf: *const c_char, size: usize) -> bool { + if self.chk_rwerror() { + return false; + } + if buf.is_null() { + error!(LOG_LABEL, "Invalid input parameter buf=nullptr errCode:{}", PARAM_INPUT_INVALID); + self.rw_error_status = ErrorStatus::Write; + return false; + } + if size == 0 { + error!(LOG_LABEL, "Invalid input parameter size={} errCode:{}", size, PARAM_INPUT_INVALID); + self.rw_error_status = ErrorStatus::Write; + return false; + } + if (self.w_pos + size as i32) > MAX_STREAM_BUF_SIZE as i32 { + error!(LOG_LABEL, "The write length exceeds buffer. wIdx:{} size:{} maxBufSize:{} errCode:{}", + self.w_pos, size, MAX_STREAM_BUF_SIZE, MEM_OUT_OF_BOUNDS); + self.rw_error_status = ErrorStatus::Write; + return false; + } + unsafe { + let pointer = &(self.sz_buff[0]) as *const c_char; + let ret = binding::memcpy_s(pointer.add(self.w_pos as usize) as *mut libc::c_void, + self.get_available_buf_size() as usize, buf as *mut libc::c_void, size); + if ret != 0 { + error!(LOG_LABEL, "Failed to call memcpy_s. ret:{}", ret); + self.rw_error_status = ErrorStatus::Write; + return false; + } + } + self.w_pos += size as i32; + self.w_count += 1; + true + } + fn check_write(&mut self, size: usize) -> bool { + let buffer_size = size as i32; + let mut avail_size = self.get_available_buf_size(); + if buffer_size > avail_size && self.r_pos > 0 { + self.copy_data_to_begin(); + avail_size = self.get_available_buf_size(); + } + avail_size >= buffer_size + } + fn copy_data_to_begin(&mut self) { + let unread_size: i32 = self.unread_size(); + if unread_size > 0 && self.r_pos > 0 { + for (index, value) in (self.r_pos..=self.w_pos).enumerate() { + self.sz_buff[index] = self.sz_buff[value as usize]; + } + } + debug!(LOG_LABEL, "unread_size:{} rPos:{} wPos:{}", unread_size, self.r_pos, self.w_pos); + self.r_pos = 0; + self.w_pos = unread_size; + } + /// read buffer + pub fn read_char_usize(&mut self, buf: *const c_char, size: usize) -> bool { + if self.chk_rwerror() { + return false; + } + if buf.is_null() { + error!(LOG_LABEL, "Invalid input parameter buf=nullptr errCode:{}", PARAM_INPUT_INVALID); + self.rw_error_status = ErrorStatus::Read; + return false; + } + if size == 0 { + error!(LOG_LABEL, "Invalid input parameter size={} errCode:{}", size, PARAM_INPUT_INVALID); + self.rw_error_status = ErrorStatus::Read; + return false; + } + if (self.r_pos + size as i32) > self.w_pos { + error!(LOG_LABEL, "Memory out of bounds on read... errCode:{}", MEM_OUT_OF_BOUNDS); + self.rw_error_status = ErrorStatus::Read; + return false; + } + unsafe { + let ret = binding::memcpy_s(buf as *mut libc::c_void, size, self.read_buf() as *const libc::c_void, size); + if ret != 0 { + error!(LOG_LABEL, "Failed to call memcpy_s. ret:{}", ret); + self.rw_error_status = ErrorStatus::Read; + return false; + } + } + self.r_pos += size as i32; + self.r_count += 1; + true + } + /// circle write + pub fn circle_write(&mut self, buf: *const c_char, size: usize) -> bool { + if !self.check_write(size) { + error!(LOG_LABEL, "Out of buffer memory, availableSize:{}, size:{}, unreadSize:{}, rPos:{}, wPos:{}", + self.get_available_buf_size(), size, self.unread_size(), + self.r_pos, self.w_pos); + return false; + } + self.write_char_usize(buf, size) + } + /// callback function + /// + ///# Safety + /// + /// call unsafe function + pub unsafe fn read_server_packets(&mut self, stream_server: *const CStreamServer, + fd: i32, callback_fun: ServerPacketCallBackFun) { + const HEAD_SIZE: i32 = size_of::() as i32; + for _i in 0.. ONCE_PROCESS_NETPACKET_LIMIT { + let unread_size: i32 = self.unread_size(); + if unread_size < HEAD_SIZE { + break; + } + let data_size :i32 = unread_size - HEAD_SIZE; + let buf: *const c_char = self.read_buf(); + if buf.is_null() { + error!(LOG_LABEL, "CHKPB(buf) is null, skip then break"); + break; + } + let head: *const PackHead = buf as *const PackHead; + if head.is_null() { + error!(LOG_LABEL, "CHKPB(head) is null, skip then break"); + break; + } + let size; + let id_msg; + unsafe { + size = (*head).size; + id_msg = (*head).id_msg; + } + if !(0..=MAX_PACKET_BUF_SIZE).contains(&(size as usize)) { + error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ + The buffer will be reset. (*head).size:{}, unreadSize:{}", size, unread_size); + self.reset(); + break; + } + if size > data_size { + break; + } + let mut pkt: NetPacket = NetPacket { + msg_id: id_msg, + ..Default::default() + }; + unsafe { + if size > 0 && + !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE as usize) as *const c_char, size as usize) { + error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ + messageid:{}, size:{}", id_msg as i32, size); + break; + } + } + if !self.seek_read_pos(pkt.get_packet_length()) { + error!(LOG_LABEL, "Set read position error, and this error cannot be recovered, and the buffer \ + will be reset. packetSize:{} unreadSize:{}", pkt.get_packet_length(), unread_size); + self.reset(); + break; + } + unsafe { + callback_fun(stream_server, fd, &mut pkt as *const NetPacket); + } + if self.is_empty() { + self.reset(); + break; + } + } + } + /// callback of client + /// + ///# Safety + /// + /// call unsafe function + pub unsafe fn read_client_packets(&mut self, client: *const CClient, callback_fun: ClientPacketCallBackFun) { + const HEAD_SIZE: i32 = size_of::() as i32; + for _i in 0.. ONCE_PROCESS_NETPACKET_LIMIT { + let unread_size: i32 = self.unread_size(); + if unread_size < HEAD_SIZE { + break; + } + let data_size :i32 = unread_size - HEAD_SIZE; + let buf: *const c_char = self.read_buf(); + if buf.is_null() { + error!(LOG_LABEL, "CHKPB(buf) is null, skip then break"); + break; + } + let head: *const PackHead = buf as *const PackHead; + if head.is_null() { + error!(LOG_LABEL, "CHKPB(head) is null, skip then break"); + break; + } + let size; + let id_msg; + unsafe { + size = (*head).size; + id_msg = (*head).id_msg; + } + if !(0..=MAX_PACKET_BUF_SIZE).contains(&(size as usize)) { + error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ + The buffer will be reset. (*head).size:{}, unreadSize:{}", size, unread_size); + self.reset(); + break; + } + if size > data_size { + break; + } + let mut pkt: NetPacket = NetPacket { + msg_id: id_msg, + ..Default::default() + }; + unsafe { + if size > 0 && + !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE as usize) as *const c_char, size as usize) { + error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ + messageid:{}, size:{}", id_msg as i32, size); + break; + } + } + if !self.seek_read_pos(pkt.get_packet_length()) { + error!(LOG_LABEL, "Set read position error, and this error cannot be recovered, and the buffer \ + will be reset. packetSize:{} unreadSize:{}", pkt.get_packet_length(), unread_size); + self.reset(); + break; + } + unsafe { + callback_fun(client, &pkt as *const NetPacket); + } + if self.is_empty() { + self.reset(); + break; + } + } + } + /// read packets + /// + ///# Safety + /// + /// call unsafe function + pub unsafe fn read_packets(&mut self, callback_fun: ReadPacketCallBackFun) { + const HEAD_SIZE: i32 = size_of::() as i32; + for _i in 0.. ONCE_PROCESS_NETPACKET_LIMIT { + let unread_size: i32 = self.unread_size(); + if unread_size < HEAD_SIZE { + break; + } + let data_size :i32 = unread_size - HEAD_SIZE; + let buf: *const c_char = self.read_buf(); + if buf.is_null() { + error!(LOG_LABEL, "CHKPB(buf) is null, skip then break"); + break; + } + let head: *const PackHead = buf as *const PackHead; + if head.is_null() { + error!(LOG_LABEL, "CHKPB(head) is null, skip then break"); + break; + } + let size; + let id_msg; + unsafe { + size = (*head).size; + id_msg = (*head).id_msg; + } + if !(0..=MAX_PACKET_BUF_SIZE).contains(&(size as usize)) { + error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ + The buffer will be reset. (*head).size:{}, unreadSize:{}", size, unread_size); + self.reset(); + break; + } + if size > data_size { + break; + } + let mut pkt: NetPacket = NetPacket { + msg_id: id_msg, + ..Default::default() + }; + unsafe { + if size > 0 && + !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE as usize) as *const c_char, size as usize) { + error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ + messageid:{}, size:{}", id_msg as i32, size); + break; + } + } + if !self.seek_read_pos(pkt.get_packet_length()) { + error!(LOG_LABEL, "Set read position error, and this error cannot be recovered, and the buffer \ + will be reset. packetSize:{} unreadSize:{}", pkt.get_packet_length(), unread_size); + self.reset(); + break; + } + callback_fun(&mut pkt as *mut NetPacket); + if self.is_empty() { + self.reset(); + break; + } + } + } + + + +} + diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs new file mode 100644 index 00000000..4ef33f5a --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::*; +use hilog_rust::{info, hilog, HiLogLabel, LogType}; +use crate::error::BufferStatusCode; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "stream_buffer_ffi" +}; +/// data +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn data(object: *const StreamBuffer) -> *const c_char { + info!(LOG_LABEL, "enter data"); + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.data() + } else { + std::ptr::null() + } +} +/// size +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn size(object: *const StreamBuffer) -> usize { + info!(LOG_LABEL, "enter size"); + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.size() + } else { + 0 + } +} +/// reset +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn reset(object: *mut StreamBuffer) -> i32 { + info!(LOG_LABEL, "enter reset"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.reset(); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::ResetFail.into() + } +} +/// clean +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn clean(object: *mut StreamBuffer) -> i32 { + info!(LOG_LABEL, "enter clean"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.clean(); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::CleanFail.into() + } +} +/// unread_size +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn unread_size(object: *mut StreamBuffer) -> i32 { + info!(LOG_LABEL, "enter unread_size"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.unread_size() + } else { + BufferStatusCode::UnreadSizeFail.into() + } +} +/// is_empty +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn is_empty(object: *const StreamBuffer) -> bool { + info!(LOG_LABEL, "enter is_empty"); + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.is_empty() + } else { + false + } +} +/// write_streambuffer +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn write_streambuffer(object: *mut StreamBuffer, buf: *const StreamBuffer) -> bool { + info!(LOG_LABEL, "enter write_streambuffer"); + if let Some(obj) = StreamBuffer::as_mut(object) { + if let Some(buffer) = StreamBuffer::as_ref(buf) { + + obj.write_streambuffer(buffer) + } else { + false + } + } else { + false + } +} +/// read_streambuffer +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn read_streambuffer(object: *const StreamBuffer, buf: *mut StreamBuffer) -> bool { + info!(LOG_LABEL, "enter read_streambuffer"); + if let Some(obj) = StreamBuffer::as_ref(object) { + if let Some(buffer) = StreamBuffer::as_mut(buf) { + obj.read_streambuffer(buffer) + } else { + false + } + } else { + false + } +} +/// chk_rwerror +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn chk_rwerror(object: *const StreamBuffer) -> bool { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.chk_rwerror() + } else { + false + } +} +/// get_error_status_remark +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn get_error_status_remark(object: *const StreamBuffer) -> *const c_char { + info!(LOG_LABEL, "enter get_error_status_remark"); + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.get_error_status_remark() + } else { + std::ptr::null() + } +} +/// write_char_usize +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn write_char_usize(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter write_char_usize"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.write_char_usize(buf, size) + } else { + false + } +} +/// check_write +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn check_write(object: *mut StreamBuffer, size: usize) -> bool { + info!(LOG_LABEL, "enter check_write"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.check_write(size) + } else { + false + } +} +/// copy_data_to_begin +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn copy_data_to_begin(object: *mut StreamBuffer) -> i32 { + info!(LOG_LABEL, "enter copy_data_to_begin"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.copy_data_to_begin(); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::CopyDataToBeginFail.into() + } +} +/// read_char_usize +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn read_char_usize(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter read_char_usize"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.read_char_usize(buf, size) + } else { + false + } +} +/// circle_write +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn circle_write(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter circle_write"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.circle_write(buf, size) + } else { + false + } +} +/// read_server_packets +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn read_server_packets(object: *mut StreamBuffer, stream_server: *const CStreamServer, + fd: i32, callback_fun: ServerPacketCallBackFun) -> i32 { + info!(LOG_LABEL,"enter read_server_packets"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.read_server_packets(stream_server, fd, callback_fun); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::ReadServerPacketsFail.into() + } +} +/// read_client_packets +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn read_client_packets(object: *mut StreamBuffer, stream_client: *const CClient, + callback_fun: ClientPacketCallBackFun) -> i32 { + info!(LOG_LABEL,"enter read_client_packets"); + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.read_client_packets(stream_client, callback_fun); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::ReadClientPacketsFail.into() + } +} +/// read_buf +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn read_buf(object: *const StreamBuffer) -> *const c_char { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.read_buf() + } else { + std::ptr::null() + } +} + diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs new file mode 100644 index 00000000..b0158cf0 --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// provide C interface to C++ for calling +pub mod ffi; +use hilog_rust::{debug, error, hilog, HiLogLabel, LogType}; +use libc::{int32_t, int64_t, c_int, c_uint}; +use std::ffi::{CString, c_char}; +use crate::net_packet::NetPacket; +use crate::stream_buffer::StreamBuffer; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "StreamSession" +}; +const MAX_PACKET_BUF_SIZE: usize = 256; +const SEND_RETRY_LIMIT: i32 = 32; +const SEND_RETRY_SLEEP_TIME: c_uint = 10000; +#[repr(C)] +struct EventTime { + id: int32_t, + event_time: int64_t, + timer_id: int32_t, +} + +/// struct stream session +#[repr(C)] +pub struct StreamSession { + /// module_type field + pub module_type: i32, + /// fd field + pub fd: i32, + /// uid field + pub uid : i32, + /// pid field + pub pid: i32, + /// token type field + pub token_type: i32, +} + +impl StreamSession { + /// return const referance of self + /// + /// # Safety + /// + /// Makesure object is null pointer + unsafe fn as_ref<'a>(object: *const Self) -> Option<&'a Self>{ + object.as_ref() + } + /// return mutable referance of self + /// + /// # Safety + /// + /// Makesure object is null pointer + unsafe fn as_mut<'a>(object: *mut Self) -> Option<&'a mut Self>{ + object.as_mut() + } + + fn uid(&self) -> i32 { + self.uid + } + fn pid(&self) -> i32 { + self.pid + } + fn module_type(&self) -> i32 { + self.module_type + } + fn session_fd(&self) -> i32 { + self.fd + } + fn set_token_type(&mut self, style: i32) { + self.token_type = style + } + fn token_type(&self) -> i32 { + self.token_type + } + fn session_close(&mut self) { + debug!(LOG_LABEL, "Enter fd_:{}.", self.fd); + if self.fd >= 0 { + unsafe { + libc::close(self.fd as c_int); + } + self.fd = -1; + } + } + fn session_send_msg(&self, buf: *const c_char, size: usize) -> bool { + if buf.is_null() { + error!(LOG_LABEL, "CHKPF(buf) is null"); + return false; + } + if size == 0 || size > MAX_PACKET_BUF_SIZE { + error!(LOG_LABEL, "buf size:{}", size); + return false; + } + if self.fd < 0 { + error!(LOG_LABEL, "The fd is less than 0"); + return false; + } + let mut idx = 0; + let mut retry_count = 0; + let buf_size = size; + let mut rem_size = buf_size; + while rem_size > 0 && retry_count < SEND_RETRY_LIMIT { + retry_count += 1; + let count; + let errno; + // safety: call libc library function which is unsafe function + unsafe { + count = libc::send(self.fd as c_int, buf.add(idx) as *const libc::c_void, + rem_size, libc::MSG_DONTWAIT | libc::MSG_NOSIGNAL); + errno = *libc::__errno_location(); + }; + if count < 0 { + if errno == libc::EAGAIN || errno == libc::EINTR || errno == libc::EWOULDBLOCK { + // safety: call libc library function which is unsafe function + unsafe { + libc::usleep(SEND_RETRY_SLEEP_TIME); + } + error!(LOG_LABEL, "Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:{}", errno); + continue; + } + error!(LOG_LABEL, "Send return failed,error:{} fd:{}", errno, self.fd); + return false; + } + idx += count as usize; + rem_size -= count as usize; + if rem_size > 0 { + // safety: call libc library function which is unsafe function + unsafe { + libc::usleep(SEND_RETRY_SLEEP_TIME); + } + } + } + if retry_count >= SEND_RETRY_LIMIT || rem_size != 0 { + error!(LOG_LABEL, "Send too many times:{}/{},size:{}/{} fd:{}", + retry_count, SEND_RETRY_LIMIT, idx, buf_size, self.fd); + return false; + } + true + } + /// session send message + pub fn send_msg_pkt(&self, pkt: &NetPacket) -> bool { + if pkt.stream_buffer.chk_rwerror() { + error!(LOG_LABEL, "Read and write status is error"); + return false; + } + let mut buf: StreamBuffer = Default::default(); + pkt.make_data(&mut buf); + self.session_send_msg(buf.data(), buf.size()) + } +} diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs new file mode 100644 index 00000000..7e676197 --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::*; +use crate::error::SessionStatusCode; +use hilog_rust::{info, hilog, HiLogLabel, LogType}; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "stream_session_ffi" +}; + +/// get_uid +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_uid(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter get_uid"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.uid() + } else { + SessionStatusCode::UidFail.into() + } +} +/// get_pid +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_pid(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter get_pid"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.pid() + } else { + SessionStatusCode::PidFail.into() + } +} +/// get module type +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_module_type(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter get_module_type"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.module_type() + } else { + SessionStatusCode::ModuleTypeFail.into() + } +} +/// get session fd +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_session_fd(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter get_session_fd"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.session_fd() + } else { + SessionStatusCode::FdFail.into() + } +} +/// get token type +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn set_token_type(object: *mut StreamSession, style: i32) -> i32 { + info!(LOG_LABEL, "enter set_token_type"); + if let Some(obj) = StreamSession::as_mut(object) { + obj.set_token_type(style); + SessionStatusCode::Ok.into() + } else { + SessionStatusCode::SetTokenTypeFail.into() + } +} +/// get token type +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_token_type(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter get_token_type"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.token_type() + } else { + SessionStatusCode::TokenTypeFail.into() + } +} +/// get session close +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn session_close(object: *mut StreamSession) -> i32 { + info!(LOG_LABEL, "enter session_close"); + if let Some(obj) = StreamSession::as_mut(object) { + obj.session_close(); + SessionStatusCode::Ok.into() + } else { + SessionStatusCode::CloseFail.into() + } +} + +/// session send message +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn session_send_msg(object: *const StreamSession, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter session_send_msg"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.session_send_msg(buf, size) + } else { + false + } +} \ No newline at end of file diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs new file mode 100644 index 00000000..64d91e22 --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// provide C interface to C++ for calling +pub mod ffi; +use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; +use std::ptr; +use libc::{c_int, c_uint}; +use std::ffi::{CString, c_char}; +const ONCE_PROCESS_NETPACKET_LIMIT: i32 = 100; +const MAX_PACKET_BUF_SIZE: usize = 256; +const SEND_RETRY_SLEEP_TIME: c_uint = 10000; +const SEND_RETRY_LIMIT: i32 = 32; + +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "StreamSocket" +}; + +/// struct StreamSocket +#[repr(C)] +pub struct StreamSocket { + /// socket_fd + pub socket_fd: i32, + /// epoll_fd + pub epoll_fd: i32, +} + +impl Default for StreamSocket { + fn default() -> Self { + Self { + socket_fd: -1, + epoll_fd: -1, + } + } +} + +impl StreamSocket { + /// return const referance of self + /// + /// # Safety + /// + /// Makesure object is null pointer + unsafe fn as_ref<'a>(object: *const Self) -> Option<&'a Self>{ + object.as_ref() + } + /// return mutable referance of self + /// + /// # Safety + /// + /// Makesure object is null pointer + unsafe fn as_mut<'a>(object: *mut Self) -> Option<&'a mut Self>{ + object.as_mut() + } + /// get socket_fd + pub fn socket_fd(&self) -> i32 { + self.socket_fd + } + /// get epoll_fd + pub fn epoll_fd(&self) -> i32 { + self.epoll_fd + } + /// adjust whether epoll_fd is valid or not + pub fn is_valid_epoll(&self) -> bool { + self.epoll_fd > 0 + } + /// create epoll_fd + pub fn create_epoll_fd(&mut self, size: i32) { + let epoll_fd; + unsafe { + epoll_fd = libc::epoll_create(size); + } + if epoll_fd < 0 { + error!(LOG_LABEL, "epoll_create return {}", epoll_fd); + } else { + self.epoll_fd = epoll_fd; + info!(LOG_LABEL, "epoll_create, epoll_fd:{}", epoll_fd); + } + } + /// event is null pointer + pub fn epoll_ctl(fd: i32, op: i32, event: *mut libc::epoll_event, epoll_fd: i32) -> i32 { + if event.is_null() { + error!(LOG_LABEL, "event is nullptr"); + return -1; + } + if op == libc::EPOLL_CTL_DEL { + // safety: call unsafe function + unsafe { + libc::epoll_ctl(epoll_fd as c_int, op as c_int, fd as c_int, ptr::null_mut()) + } + } else { + // safety: call unsafe function + unsafe { + libc::epoll_ctl(epoll_fd as c_int, op as c_int, fd as c_int, event as *mut libc::epoll_event) + } + } + } + /// epoll_wait + /// + /// # Safety + /// + /// call libc + pub unsafe fn epoll_wait(events: *mut libc::epoll_event, maxevents: i32, timeout: i32, epoll_fd: i32) -> i32 { + let ret = libc::epoll_wait( + epoll_fd as c_int, events as *mut libc::epoll_event, maxevents as c_int, timeout as c_int); + if ret < 0 { + let errno = *libc::__errno_location(); + error!(LOG_LABEL, "epoll_wait ret:{},errno:{}", ret, errno); + } + ret + } + /// epoll close + pub fn epoll_close(&mut self) { + if self.epoll_fd >= 0 { + unsafe { + libc::close(self.epoll_fd as c_int); + } + self.epoll_fd = -1; + } + } + /// socket close + pub fn socket_close(&mut self) { + if self.socket_fd >= 0 { + unsafe { + let rf = libc::close(self.socket_fd as c_int); + if rf > 0 { + error!(LOG_LABEL, "Socket close failed rf:{}", rf); + } + } + self.socket_fd = -1; + } + } + /// send message + /// + /// # Safety + /// + /// call unsafe function + pub unsafe fn send_msg(&self, buf: *const u8, size: usize) -> bool { + if buf.is_null() { + error!(LOG_LABEL, "CHKPF(buf) is null"); + return false; + } + if size == 0 || size > MAX_PACKET_BUF_SIZE { + error!(LOG_LABEL, "Stream buffer size out of range"); + return false; + } + if self.socket_fd < 0 { + error!(LOG_LABEL, "The fd_ is less than 0"); + return false; + } + let mut idx = 0; + let mut retry_count = 0; + let buf_size = size; + let mut rem_size = buf_size; + while rem_size > 0 && retry_count < SEND_RETRY_LIMIT { + retry_count += 1; + let count; + let errno; + unsafe { + count = libc::send(self.socket_fd as c_int, buf.add(idx) as *const libc::c_void, + rem_size, libc::MSG_DONTWAIT | libc::MSG_NOSIGNAL); + errno = *libc::__errno_location(); + } + if count < 0 { + if errno == libc::EAGAIN || errno == libc::EINTR || errno == libc::EWOULDBLOCK { + error!(LOG_LABEL, "Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:{}", errno); + continue; + } + error!(LOG_LABEL, "Send return failed,error:{} fd:{}", errno, self.socket_fd); + return false; + } + idx += count as usize; + rem_size -= count as usize; + if rem_size > 0 { + unsafe { + libc::usleep(SEND_RETRY_SLEEP_TIME); + } + } + } + if retry_count >= SEND_RETRY_LIMIT || rem_size != 0 { + error!(LOG_LABEL, "Send too many times:{}/{},size:{}/{} fd:{}", + retry_count, SEND_RETRY_LIMIT, idx, buf_size, self.socket_fd); + return false; + } + true + } + +} + + diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs new file mode 100644 index 00000000..68f18065 --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::*; +use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; +use crate::error::SocketStatusCode; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xD002220, + tag: "stream_socket_ffi" +}; + +/// Get Fd +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_fd(object: *const StreamSocket) -> i32 { + info!(LOG_LABEL, "enter get_fd"); + // 等价于 + // let obj = object.as_ref() ; + // match obj { + // Some(obj) => obj.fd(), + // None => return -1; + // } + if let Some(obj) = StreamSocket::as_ref(object) { + obj.socket_fd() + } else { + SocketStatusCode::FdFail.into() + } +} + +/// Get Fd +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn get_epoll_fd(object: *const StreamSocket) -> i32 { + info!(LOG_LABEL, "enter get_epoll_fd"); + if let Some(obj) = StreamSocket::as_ref(object) { + obj.epoll_fd() + } else { + SocketStatusCode::EpollFdFail.into() + } +} + +/// Get Fd +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn rust_epoll_create(object: *mut StreamSocket, size: i32) -> i32 { + info!(LOG_LABEL, "enter rust_epoll_create"); + + if let Some(obj) = StreamSocket::as_mut(object) { + obj.create_epoll_fd(size); + obj.epoll_fd() + } else { + SocketStatusCode::EpollCreateFail.into() + } + +} + +/// rust_epoll_ctl +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn rust_epoll_ctl(object: *const StreamSocket, fd: i32, op: i32, + event: *mut libc::epoll_event, epoll_fd: i32) -> i32 { + info!(LOG_LABEL, "enter rust_epoll_ctl"); + if let Some(obj) = StreamSocket::as_ref(object) { + if fd < 0 { + error!(LOG_LABEL, "Invalid fd"); + return -1 + } + let epoll_fd = + if epoll_fd < 0 { + if obj.is_valid_epoll(){ + obj.epoll_fd() + } else { + return -1; + } + } else { + epoll_fd + }; + StreamSocket::epoll_ctl(fd, op, event, epoll_fd) + } else { + SocketStatusCode::EpollCtlFail.into() + } +} + +/// rust_epoll_wait +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn rust_epoll_wait( + object: *const StreamSocket, events: *mut libc::epoll_event, maxevents: i32, timeout: i32, epoll_fd: i32) -> i32 { + info!(LOG_LABEL, "enter rust_epoll_wait"); + if let Some(obj) = StreamSocket::as_ref(object) { + let epoll_fd = + if epoll_fd < 0 { + if obj.is_valid_epoll() { + obj.epoll_fd() + } else { + return -1; + } + } else { + epoll_fd + }; + StreamSocket::epoll_wait(events, maxevents, timeout, epoll_fd) + } else { + SocketStatusCode::EpollWaitFail.into() + } +} + +/// rust_epoll_close +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn rust_epoll_close(object: *mut StreamSocket) -> i32 { + info!(LOG_LABEL, "enter rust_epoll_close"); + if let Some(obj) = StreamSocket::as_mut(object) { + obj.epoll_close(); + SocketStatusCode::Ok.into() + } else { + SocketStatusCode::EpollCloseFail.into() + } +} +/// rust_close +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn rust_close(object: *mut StreamSocket) -> i32 { + info!(LOG_LABEL, "enter rust_close"); + if let Some(obj) = StreamSocket::as_mut(object) { + obj.socket_close(); + SocketStatusCode::Ok.into() + } else { + SocketStatusCode::SocketCloseFail.into() + } +} +/// send_msg_buf_size +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn send_msg_buf_size(object: *const StreamSocket, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter send_msg_buf_size"); + if let Some(obj) = StreamSocket::as_ref(object) { + obj.send_msg(buf, size) + } else { + false + } +} + diff --git a/rust/utils/socket_ipc_rust_ffi/test/main.rs b/rust/utils/socket_ipc_rust_ffi/test/main.rs new file mode 100644 index 00000000..a1d8609b --- /dev/null +++ b/rust/utils/socket_ipc_rust_ffi/test/main.rs @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! socket communication example +#![feature(rustc_private)] + +extern crate sensor_rust_util; +extern crate libc; +use libc::c_int; +use libc::c_char; +use sensor_rust_util::stream_session::StreamSession; +use sensor_rust_util::net_packet::NetPacket; +use sensor_rust_util::net_packet::MessageId; +use sensor_rust_util::stream_socket::StreamSocket; +use sensor_rust_util::stream_buffer::{StreamBuffer, MAX_PACKET_BUF_SIZE}; +use std::mem::size_of; + +unsafe fn read_packets_callback(pkt: *mut NetPacket) { + if let Some(obj) = NetPacket::as_mut(pkt) { + println!("msg_id={}", obj.msg_id as i32); + let mut d: i32 = 0; + let mut e: i32 = 0; + let mut f: i32 = 0; + obj.read(&mut d); + obj.read(&mut e); + obj.read(&mut f); + println!("d={},e={},f={}", d, e, f); + } else { + + } +} + +fn main() { + const MAX_EVENT_SIZE: i32 = 100; + let mut socket_fds: [c_int; 2] = [-1; 2]; + unsafe { + if libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, &mut socket_fds[0]) != 0 { + println!("Call socketpair failed"); + } + } + let server_fd = socket_fds[0]; + let client_fd = socket_fds[1]; + let buffer_size: libc::size_t = 32 * 1024; + + println!("server_fd={}, client_fd={}", server_fd, client_fd); + unsafe { + let pid: libc::pid_t = libc::fork(); + if pid == -1 { + println!("Error: fork failed."); + } else if pid == 0 { + println!("I am the child process, my PID is {}.", libc::getpid()); + libc::close(server_fd); + if libc::setsockopt(client_fd, libc::SOL_SOCKET, libc::SO_SNDBUF, + &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { + println!("setsockopt client_fd failed"); + } + if libc::setsockopt(client_fd, libc::SOL_SOCKET, libc::SO_RCVBUF, + &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { + println!("setsockopt client_fd failed"); + } + let mut events: [libc::epoll_event; MAX_EVENT_SIZE as usize] = [ + libc::epoll_event { + events: 0, + u64: 0, + }; MAX_EVENT_SIZE as usize + ]; + let mut stream_socket: StreamSocket = Default::default(); + let mut ev: libc::epoll_event= libc::epoll_event { + events: 0, + u64: 0, + }; + ev.events = libc::EPOLLIN as u32; + ev.u64 = client_fd as u64; + stream_socket.create_epoll_fd(MAX_EVENT_SIZE); + if StreamSocket::epoll_ctl(client_fd, libc::EPOLL_CTL_ADD, &mut ev, stream_socket.epoll_fd) != 0 { + println!("epoll_ctl fail"); + } + loop { + let _count: i32 = StreamSocket::epoll_wait(&mut events[0], MAX_EVENT_SIZE, -1, stream_socket.epoll_fd); + let mut sz_buf: [c_char; MAX_PACKET_BUF_SIZE] = [0; MAX_PACKET_BUF_SIZE]; + let mut buf: StreamBuffer = Default::default(); + let size = libc::recv(client_fd, &mut sz_buf[0] as *mut c_char as *mut libc::c_void, + MAX_PACKET_BUF_SIZE, libc::MSG_DONTWAIT | libc::MSG_NOSIGNAL); + if !buf.circle_write(&sz_buf[0], size as usize) { + println!("Write data failed. size:{}", size); + } + buf.read_packets(read_packets_callback); + } + } else { + println!("I am the parent process, my PID is {} and my child's PID is {}", libc::getpid(), pid); + libc::close(client_fd); + if libc::setsockopt(server_fd, libc::SOL_SOCKET, libc::SO_SNDBUF, + &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { + println!("setsockopt server_fd failed"); + } + if libc::setsockopt(server_fd, libc::SOL_SOCKET, libc::SO_RCVBUF, + &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { + println!("setsockopt serverFd failed"); + } + let session: StreamSession = StreamSession { + module_type: 0, + fd: server_fd, + uid : 0, + pid, + token_type: 0, + }; + loop { + let mut pkt: NetPacket = NetPacket { + msg_id: MessageId::DragNotifyResult, + ..Default::default() + }; + let a: i32 = 777; + let b: i32 = 888; + let c: i32 = 999; + pkt.write(a); + pkt.write(b); + pkt.write(c); + session.send_msg_pkt(&pkt); + libc::usleep(1000000); + } + } + } +} \ No newline at end of file diff --git a/sensor.gni b/sensor.gni new file mode 100644 index 00000000..86cf839a --- /dev/null +++ b/sensor.gni @@ -0,0 +1,26 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +declare_args() { + rust_socket_ipc = false +} + +SUBSYSTEM_DIR = "//base/sensors/sensor" + +sensor_default_defines = [] + +if (rust_socket_ipc) { + sensor_default_defines += [ "OHOS_BUILD_ENABLE_RUST" ] +} diff --git a/services/sensor/BUILD.gn b/services/sensor/BUILD.gn index 6356df68..497c3ab0 100644 --- a/services/sensor/BUILD.gn +++ b/services/sensor/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//base/sensors/sensor/sensor.gni") import("//build/ohos.gni") SUBSYSTEM_DIR = "//base/sensors" @@ -47,11 +48,17 @@ ohos_shared_library("libsensor_service") { "hdi_connection/hardware/include", ] + defines = sensor_default_defines + deps = [ "$SUBSYSTEM_DIR/sensor/utils/common:libsensor_utils", "$SUBSYSTEM_DIR/sensor/utils/ipc:libsensor_ipc", ] + if (rust_socket_ipc) { + deps += [ "$SUBSYSTEM_DIR/sensor/rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] + } + external_deps = [ "access_token:libaccesstoken_sdk", "c_utils:utils", diff --git a/services/sensor/src/sensor_power_policy.cpp b/services/sensor/src/sensor_power_policy.cpp index b466037f..2d3e64e5 100644 --- a/services/sensor/src/sensor_power_policy.cpp +++ b/services/sensor/src/sensor_power_policy.cpp @@ -194,7 +194,11 @@ void SensorPowerPolicy::ReportActiveInfo(const ActiveInfo &activeInfo, NetPacket pkt(MessageId::ACTIVE_INFO); pkt << activeInfo.GetPid() << activeInfo.GetSensorId() << activeInfo.GetSamplingPeriodNs() << activeInfo.GetMaxReportDelayNs(); +#ifdef OHOS_BUILD_ENABLE_RUST + if (chk_rwerror(&pkt.rustStreamBuffer_)) { +#else if (pkt.ChkRWError()) { +#endif // OHOS_BUILD_ENABLE_RUST SEN_HILOGE("Packet write data failed"); return; } diff --git a/utils/ipc/BUILD.gn b/utils/ipc/BUILD.gn index 6e579be0..4a528a13 100644 --- a/utils/ipc/BUILD.gn +++ b/utils/ipc/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//base/sensors/sensor/sensor.gni") import("//build/ohos.gni") ohos_shared_library("libsensor_ipc") { @@ -27,6 +28,12 @@ ohos_shared_library("libsensor_ipc") { "./../common/include", ] + defines = sensor_default_defines + + if (rust_socket_ipc) { + deps = [ "../../rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] + } + external_deps = [ "access_token:libaccesstoken_sdk", "c_utils:utils", diff --git a/utils/ipc/include/rust_binding.h b/utils/ipc/include/rust_binding.h new file mode 100644 index 00000000..c3de741d --- /dev/null +++ b/utils/ipc/include/rust_binding.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RUST_BINDING_H +#define RUST_BINDING_H +#include +#include +#include "proto.h" +#include "accesstoken_kit.h" + +extern "C" { + enum class ErrorStatus : int32_t { + ERROR_STATUS_Ok = 0, + ERROR_STATUS_Read = 1, + ERROR_STATUS_Write = 2, + }; + struct RustStreamSocket { + int32_t fd_ { -1 }; + int32_t epollFd_ { -1 }; + }; + struct RustStreamSession { + int32_t moduleType_ { -1 }; + int32_t fd_ { -1 }; + int32_t uid_ { -1 }; + int32_t pid_ { -1 }; + int32_t tokenType_ { OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_INVALID }; + }; + struct RustStreamClient { + bool isExit { false }; + bool isRunning_ { false }; + bool isConnected_ { false }; + }; + struct RustStreamBuffer { + ErrorStatus rwErrorStatus_ { ErrorStatus::ERROR_STATUS_Ok }; + int32_t rCount_ { 0 }; + int32_t wCount_ { 0 }; + int32_t rPos_ { 0 }; + int32_t wPos_ { 0 }; + char szBuff_[OHOS::Sensors::MAX_STREAM_BUF_SIZE+1] { }; + }; + struct RustNetPacket { + OHOS::Sensors::MessageId msgId_ { OHOS::Sensors::MessageId::INVALID }; + struct RustStreamBuffer rustStreamBuffer; + }; + int32_t get_fd(const RustStreamSocket*); + int32_t get_epoll_fd(const RustStreamSocket*); + int32_t rust_epoll_create(RustStreamSocket*, int32_t); + int32_t rust_epoll_ctl(RustStreamSocket*, int32_t, int32_t, struct epoll_event*, int32_t); + int32_t rust_epoll_wait(RustStreamSocket*, struct epoll_event*, int32_t, int32_t, int32_t); + int32_t rust_epoll_close(RustStreamSocket*); + int32_t rust_close(RustStreamSocket*); + bool send_msg_buf_size(const RustStreamSocket*, const char*, size_t); + void session_close(RustStreamSession*); + bool session_send_msg(const RustStreamSession*, const char*, size_t); + bool get_connected_status(const RustStreamClient&); + void stop(RustStreamClient&, RustStreamSocket&); + void reset(RustStreamBuffer*); + void clean(RustStreamBuffer*); + bool read_streambuffer(RustStreamBuffer*, RustStreamBuffer*); + bool write_streambuffer(RustStreamBuffer*, const RustStreamBuffer*); + const char* read_buf(const RustStreamBuffer*); + bool read_char_usize(RustStreamBuffer*, char *, size_t); + bool write_char_usize(RustStreamBuffer*, const char*, size_t); + const char* data(const RustStreamBuffer*); + size_t size(const RustStreamBuffer*); + int32_t unread_size(RustStreamBuffer*); + int32_t get_available_buf_size(RustStreamBuffer*); + const char* get_error_status_remark(const RustStreamBuffer*); + bool chk_rwerror(const RustStreamBuffer*); + bool check_write(RustStreamBuffer*, size_t); + bool circle_write(RustStreamBuffer*, const char*, size_t); + void copy_data_to_begin(RustStreamBuffer*); + int32_t get_uid(const RustStreamSession*); + int32_t get_pid(const RustStreamSession*); + int32_t get_module_type(const RustStreamSession*); + int32_t get_session_fd(const RustStreamSession*); + void set_token_type(RustStreamSession*, int32_t type); + int32_t get_token_type(const RustStreamSession*); + bool seek_read_pos(RustStreamBuffer*, int32_t); + const char* read_buf(const RustStreamBuffer*); + bool is_empty(const RustStreamBuffer*); + size_t get_size(const RustNetPacket*); + int32_t get_packet_length(const RustNetPacket*); + const char* get_data(const RustNetPacket*); + OHOS::Sensors::MessageId get_msg_id(const RustNetPacket*); +} +#endif // RUST_BINDING_H \ No newline at end of file diff --git a/utils/ipc/include/stream_buffer.h b/utils/ipc/include/stream_buffer.h index a7cdcfa0..591555e7 100644 --- a/utils/ipc/include/stream_buffer.h +++ b/utils/ipc/include/stream_buffer.h @@ -26,6 +26,10 @@ #include "proto.h" #include "sensors_errors.h" +#ifdef OHOS_BUILD_ENABLE_RUST +#include "rust_binding.h" +#endif // OHOS_BUILD_ENABLE_RUST + namespace OHOS { namespace Sensors { class StreamBuffer { @@ -37,13 +41,14 @@ public: virtual ~StreamBuffer() = default; void Reset(); void Clean(); - bool SeekReadPos(size_t n); bool Read(std::string &buf); bool Read(StreamBuffer &buf); bool Read(char *buf, size_t size); bool Write(const std::string &buf); bool Write(const StreamBuffer &buf); virtual bool Write(const char *buf, size_t size); +#ifndef OHOS_BUILD_ENABLE_RUST + bool SeekReadPos(size_t n); bool IsEmpty() const; bool ChkRWError() const; size_t Size() const; @@ -51,7 +56,8 @@ public: size_t GetAvailableBufSize() const; const std::string& GetErrorStatusRemark() const; const char* Data() const; - + const char *WriteBuf() const; +#endif // OHOS_BUILD_ENABLE_RUST template bool Read(T &data); template @@ -61,7 +67,7 @@ public: template bool Write(const std::vector &data); const char *ReadBuf() const; - const char *WriteBuf() const; + template StreamBuffer &operator >> (T &data); template @@ -70,6 +76,10 @@ public: protected: bool Clone(const StreamBuffer &buf); +#ifdef OHOS_BUILD_ENABLE_RUST +public: + struct RustStreamBuffer rustStreamBuffer_; +#else enum class ErrorStatus { ERROR_STATUS_OK, ERROR_STATUS_READ, @@ -81,14 +91,22 @@ protected: size_t rPos_ { 0 }; size_t wPos_ { 0 }; char szBuff_[MAX_STREAM_BUF_SIZE + 1] = {}; +#endif // OHOS_BUILD_ENABLE_RUST + }; template bool StreamBuffer::Read(T &data) { if (!Read(reinterpret_cast(&data), sizeof(data))) { +#ifdef OHOS_BUILD_ENABLE_RUST + const char* s = get_error_status_remark(&rustStreamBuffer_); + SEN_HILOGE("[%{public}s] size:%{public}zu count:%{public}d", + s, sizeof(data), rustStreamBuffer_.rCount_ + 1); +#else SEN_HILOGE("%{public}s, size:%{public}zu, count:%{public}zu", GetErrorStatusRemark().c_str(), sizeof(data), rCount_ + 1); +#endif // OHOS_BUILD_ENABLE_RUST return false; } return true; @@ -98,8 +116,14 @@ template bool StreamBuffer::Write(const T &data) { if (!Write(reinterpret_cast(&data), sizeof(data))) { +#ifdef OHOS_BUILD_ENABLE_RUST + const char* s = get_error_status_remark(&rustStreamBuffer_); + SEN_HILOGE("[%{public}s] size:%{public}zu,count:%{public}d", + s, sizeof(data), rustStreamBuffer_.wCount_ + 1); +#else SEN_HILOGE("%{public}s, size:%{public}zu, count:%{public}zu", GetErrorStatusRemark().c_str(), sizeof(data), wCount_ + 1); +#endif // OHOS_BUILD_ENABLE_RUST return false; } return true; diff --git a/utils/ipc/include/stream_session.h b/utils/ipc/include/stream_session.h index 55a991e9..88dee8c4 100644 --- a/utils/ipc/include/stream_session.h +++ b/utils/ipc/include/stream_session.h @@ -28,6 +28,10 @@ #include "net_packet.h" #include "proto.h" +#ifdef OHOS_BUILD_ENABLE_RUST +#include "rust_binding.h" +#endif // OHOS_BUILD_ENABLE_RUST + namespace OHOS { namespace Sensors { @@ -61,10 +65,14 @@ protected: std::map> events_; std::string descript_; const std::string programName_; +#ifdef OHOS_BUILD_ENABLE_RUST + struct RustStreamSession rustStreamSession_; +#else int32_t fd_ { -1 }; const int32_t uid_ { -1 }; const int32_t pid_ { -1 }; int32_t tokenType_ { ATokenTypeEnum::TOKEN_INVALID }; +#endif // OHOS_BUILD_ENABLE_RUST }; } // namespace Sensors } // namespace OHOS diff --git a/utils/ipc/include/stream_socket.h b/utils/ipc/include/stream_socket.h index d70d6d1c..da3f32f4 100644 --- a/utils/ipc/include/stream_socket.h +++ b/utils/ipc/include/stream_socket.h @@ -31,6 +31,9 @@ #include "circle_stream_buffer.h" #include "net_packet.h" +#ifdef OHOS_BUILD_ENABLE_RUST +#include "rust_binding.h" +#endif // OHOS_BUILD_ENABLE_RUST namespace OHOS { namespace Sensors { @@ -42,17 +45,23 @@ public: int32_t EpollCreate(int32_t size); int32_t EpollCtl(int32_t fd, int32_t op, struct epoll_event &event, int32_t epollFd = -1); int32_t EpollWait(struct epoll_event &events, int32_t maxevents, int32_t timeout, int32_t epollFd = -1); - void OnReadPackets(CircleStreamBuffer &buf, PacketCallBackFun callbackFun); void EpollClose(); void Close(); int32_t GetFd() const; int32_t GetEpollFd() const; - +#ifndef OHOS_BUILD_ENABLE_RUST + void OnReadPackets(CircleStreamBuffer &buf, PacketCallBackFun callbackFun); +#endif // OHOS_BUILD_ENABLE_RUST DISALLOW_COPY_AND_MOVE(StreamSocket); protected: +#ifdef OHOS_BUILD_ENABLE_RUST + struct RustStreamSocket rustStreamSocket_; +#else int32_t fd_ { -1 }; int32_t epollFd_ { -1 }; +#endif // OHOS_BUILD_ENABLE_RUST + }; } // namespace Sensors } // namespace OHOS diff --git a/utils/ipc/src/circle_stream_buffer.cpp b/utils/ipc/src/circle_stream_buffer.cpp index c086b695..e526b5b1 100644 --- a/utils/ipc/src/circle_stream_buffer.cpp +++ b/utils/ipc/src/circle_stream_buffer.cpp @@ -1,57 +1,69 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "circle_stream_buffer.h" - -#include "sensors_errors.h" - -namespace OHOS { -namespace Sensors { -bool CircleStreamBuffer::CheckWrite(size_t size) -{ - size_t availSize = GetAvailableBufSize(); - if (size > availSize && rPos_ > 0) { - CopyDataToBegin(); - availSize = GetAvailableBufSize(); - } - return (availSize >= size); -} - -bool CircleStreamBuffer::Write(const char *buf, size_t size) -{ - if (!CheckWrite(size)) { - SEN_HILOGE("Buffer is overflow, availableSize:%{public}zu, size:%{public}zu," - "unreadSize:%{public}zu, rPos:%{public}zu, wPos:%{public}zu", - GetAvailableBufSize(), size, UnreadSize(), rPos_, wPos_); - return false; - } - return StreamBuffer::Write(buf, size); -} - -void CircleStreamBuffer::CopyDataToBegin() -{ - size_t unreadSize = UnreadSize(); - if (unreadSize > 0 && rPos_ > 0) { - size_t pos = 0; - for (size_t i = rPos_; i <= wPos_;) { - szBuff_[pos++] = szBuff_[i++]; - } - } - SEN_HILOGD("UnreadSize:%{public}zu, rPos:%{public}zu, wPos:%{public}zu", unreadSize, rPos_, wPos_); - rPos_ = 0; - wPos_ = unreadSize; -} -} // namespace Sensors +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "circle_stream_buffer.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +bool CircleStreamBuffer::CheckWrite(size_t size) +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return check_write(&rustStreamBuffer_, size); +#else + size_t availSize = GetAvailableBufSize(); + if (size > availSize && rPos_ > 0) { + CopyDataToBegin(); + availSize = GetAvailableBufSize(); + } + return (availSize >= size); +#endif // OHOS_BUILD_ENABLE_RUST +} + +bool CircleStreamBuffer::Write(const char *buf, size_t size) +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return circle_write(&rustStreamBuffer_, buf, size); +#else + if (!CheckWrite(size)) { + SEN_HILOGE("Buffer is overflow, availableSize:%{public}zu, size:%{public}zu," + "unreadSize:%{public}zu, rPos:%{public}zu, wPos:%{public}zu", + GetAvailableBufSize(), size, UnreadSize(), rPos_, wPos_); + return false; + } + return StreamBuffer::Write(buf, size); +#endif // OHOS_BUILD_ENABLE_RUST +} + +void CircleStreamBuffer::CopyDataToBegin() +{ +#ifdef OHOS_BUILD_ENABLE_RUST + copy_data_to_begin(&rustStreamBuffer_); +#else + size_t unreadSize = UnreadSize(); + if (unreadSize > 0 && rPos_ > 0) { + size_t pos = 0; + for (size_t i = rPos_; i <= wPos_;) { + szBuff_[pos++] = szBuff_[i++]; + } + } + SEN_HILOGD("UnreadSize:%{public}zu, rPos:%{public}zu, wPos:%{public}zu", unreadSize, rPos_, wPos_); + rPos_ = 0; + wPos_ = unreadSize; +#endif // OHOS_BUILD_ENABLE_RUST +} +} // namespace Sensors } // namespace OHOS \ No newline at end of file diff --git a/utils/ipc/src/net_packet.cpp b/utils/ipc/src/net_packet.cpp index 27dec89b..11050645 100644 --- a/utils/ipc/src/net_packet.cpp +++ b/utils/ipc/src/net_packet.cpp @@ -1,62 +1,85 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "net_packet.h" - -#include "sensors_errors.h" - -namespace OHOS { -namespace Sensors { -NetPacket::NetPacket(MessageId msgId) : msgId_(msgId) -{} - -NetPacket::NetPacket(const NetPacket &pkt) : NetPacket(pkt.GetMsgId()) -{ - Clone(pkt); -} - -void NetPacket::MakeData(StreamBuffer &buf) const -{ - PACKHEAD head = {msgId_, wPos_}; - buf << head; - if (wPos_ > 0) { - if (!buf.Write(&szBuff_[0], wPos_)) { - SEN_HILOGE("Write data to stream failed"); - return; - } - } -} - -size_t NetPacket::GetSize() const -{ - return Size(); -} - -size_t NetPacket::GetPacketLength() const -{ - return sizeof(PackHead) + wPos_; -} - -const char* NetPacket::GetData() const -{ - return Data(); -} - -MessageId NetPacket::GetMsgId() const -{ - return msgId_; -} -} // namespace Sensors -} // namespace OHOS +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "net_packet.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +NetPacket::NetPacket(MessageId msgId) : msgId_(msgId) +{} + +NetPacket::NetPacket(const NetPacket &pkt) : NetPacket(pkt.GetMsgId()) +{ + Clone(pkt); +} + +void NetPacket::MakeData(StreamBuffer &buf) const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + PACKHEAD head = {msgId_, rustStreamBuffer_.wPos_}; + buf << head; + if (rustStreamBuffer_.wPos_ > 0) { + if (!buf.Write(&rustStreamBuffer_.szBuff_[0], rustStreamBuffer_.wPos_)) { + SEN_HILOGE("Write data to stream failed"); + return; + } + } +#else + PACKHEAD head = {msgId_, wPos_}; + buf << head; + if (wPos_ > 0) { + if (!buf.Write(&szBuff_[0], wPos_)) { + SEN_HILOGE("Write data to stream failed"); + return; + } + } +#endif // OHOS_BUILD_ENABLE_RUST +} + +size_t NetPacket::GetSize() const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return size(&rustStreamBuffer_); +#else + return Size(); +#endif // OHOS_BUILD_ENABLE_RUST +} + +size_t NetPacket::GetPacketLength() const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return (static_cast(sizeof(PackHead)) + rustStreamBuffer_.wPos_); +#else + return sizeof(PackHead) + wPos_; +#endif // OHOS_BUILD_ENABLE_RUST +} + +const char* NetPacket::GetData() const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return data(&rustStreamBuffer_); +#else + return Data(); +#endif // OHOS_BUILD_ENABLE_RUST +} + +MessageId NetPacket::GetMsgId() const +{ + return msgId_; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/ipc/src/stream_buffer.cpp b/utils/ipc/src/stream_buffer.cpp index 6b9fe1de..3ac83c66 100644 --- a/utils/ipc/src/stream_buffer.cpp +++ b/utils/ipc/src/stream_buffer.cpp @@ -15,9 +15,6 @@ #include "stream_buffer.h" -#include -#include - namespace OHOS { namespace Sensors { StreamBuffer::StreamBuffer(const StreamBuffer &buf) @@ -33,36 +30,43 @@ StreamBuffer &StreamBuffer::operator=(const StreamBuffer &other) void StreamBuffer::Reset() { +#ifdef OHOS_BUILD_ENABLE_RUST + reset(&rustStreamBuffer_); +#else rPos_ = 0; wPos_ = 0; rCount_ = 0; wCount_ = 0; rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK; +#endif // OHOS_BUILD_ENABLE_RUST } void StreamBuffer::Clean() { +#ifdef OHOS_BUILD_ENABLE_RUST + clean(&rustStreamBuffer_); +#else Reset(); errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_)); if (ret != EOK) { SEN_HILOGE("Call memset_s fail"); return; } +#endif // OHOS_BUILD_ENABLE_RUST } -bool StreamBuffer::SeekReadPos(size_t n) +bool StreamBuffer::Read(std::string &buf) { - size_t pos = rPos_ + n; - if (pos > wPos_) { - SEN_HILOGE("The position in the calculation is not as expected. pos:%{public}zu, [0, %{public}zu]", pos, wPos_); +#ifdef OHOS_BUILD_ENABLE_RUST + if (rustStreamBuffer_.rPos_ == rustStreamBuffer_.wPos_) { + SEN_HILOGE("Not enough memory to read, errCode:%{public}d", STREAM_BUF_READ_FAIL); + rustStreamBuffer_.rwErrorStatus_ = ErrorStatus::ERROR_STATUS_Read; return false; } - rPos_ = pos; - return true; -} - -bool StreamBuffer::Read(std::string &buf) -{ + buf = ReadBuf(); + rustStreamBuffer_.rPos_ += static_cast(buf.length()) + 1; + return (buf.length() > 0); +#else if (rPos_ == wPos_) { SEN_HILOGE("Not enough memory to read"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; @@ -71,25 +75,37 @@ bool StreamBuffer::Read(std::string &buf) buf = ReadBuf(); rPos_ += buf.length() + 1; return (buf.length() > 0); +#endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Write(const std::string &buf) { - return Write(buf.c_str(), buf.length() + 1); + return Write(buf.c_str(), buf.length()+1); } bool StreamBuffer::Read(StreamBuffer &buf) { +#ifdef OHOS_BUILD_ENABLE_RUST + return read_streambuffer(&rustStreamBuffer_, &buf.rustStreamBuffer_); +#else return buf.Write(Data(), Size()); +#endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Write(const StreamBuffer &buf) { +#ifdef OHOS_BUILD_ENABLE_RUST + return write_streambuffer(&rustStreamBuffer_, &buf.rustStreamBuffer_); +#else return Write(buf.Data(), buf.Size()); +#endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Read(char *buf, size_t size) { +#ifdef OHOS_BUILD_ENABLE_RUST + return read_char_usize(&rustStreamBuffer_, buf, size); +#else if (ChkRWError()) { return false; } @@ -117,10 +133,15 @@ bool StreamBuffer::Read(char *buf, size_t size) rPos_ += size; ++rCount_; return true; +#endif // OHOS_BUILD_ENABLE_RUST + } bool StreamBuffer::Write(const char *buf, size_t size) { +#ifdef OHOS_BUILD_ENABLE_RUST + return write_char_usize(&rustStreamBuffer_, buf, size); +#else if (ChkRWError()) { return false; } @@ -149,6 +170,37 @@ bool StreamBuffer::Write(const char *buf, size_t size) wPos_ += size; ++wCount_; return true; +#endif // OHOS_BUILD_ENABLE_RUST +} + +const char *StreamBuffer::ReadBuf() const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return read_buf(&rustStreamBuffer_); +#else + return &szBuff_[rPos_]; +#endif // OHOS_BUILD_ENABLE_RUST +} + +bool StreamBuffer::Clone(const StreamBuffer &buf) +{ + Clean(); +#ifdef OHOS_BUILD_ENABLE_RUST + return Write(data(&buf.rustStreamBuffer_), size(&buf.rustStreamBuffer_)); +#else + return Write(buf.Data(), buf.Size()); +#endif // OHOS_BUILD_ENABLE_RUST +} +#ifndef OHOS_BUILD_ENABLE_RUST +bool StreamBuffer::SeekReadPos(size_t n) +{ + size_t pos = rPos_ + n; + if (pos > wPos_) { + SEN_HILOGE("The position in the calculation is not as expected. pos:%{public}zu, [0, %{public}zu]", pos, wPos_); + return false; + } + rPos_ = pos; + return true; } bool StreamBuffer::IsEmpty() const @@ -156,6 +208,11 @@ bool StreamBuffer::IsEmpty() const return (rPos_ == wPos_); } +bool StreamBuffer::ChkRWError() const +{ + return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK); +} + size_t StreamBuffer::Size() const { return wPos_; @@ -171,11 +228,6 @@ size_t StreamBuffer::GetAvailableBufSize() const return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_)); } -bool StreamBuffer::ChkRWError() const -{ - return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK); -} - const std::string &StreamBuffer::GetErrorStatusRemark() const { static const std::vector> remark { @@ -195,20 +247,10 @@ const char *StreamBuffer::Data() const return &szBuff_[0]; } -const char *StreamBuffer::ReadBuf() const -{ - return &szBuff_[rPos_]; -} - const char *StreamBuffer::WriteBuf() const { return &szBuff_[wPos_]; } - -bool StreamBuffer::Clone(const StreamBuffer &buf) -{ - Clean(); - return Write(buf.Data(), buf.Size()); -} +#endif // OHOS_BUILD_ENABLE_RUST } // namespace Sensors } // namespace OHOS diff --git a/utils/ipc/src/stream_session.cpp b/utils/ipc/src/stream_session.cpp index 4c0318db..92618dda 100644 --- a/utils/ipc/src/stream_session.cpp +++ b/utils/ipc/src/stream_session.cpp @@ -34,16 +34,30 @@ constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "St } StreamSession::StreamSession(const std::string &programName, const int32_t fd, const int32_t uid, const int32_t pid) - : programName_(programName), + : programName_(programName) +#ifdef OHOS_BUILD_ENABLE_RUST +{ + rustStreamSession_.fd_ = fd; + rustStreamSession_.uid_ = uid; + rustStreamSession_.pid_ = pid; + UpdateDescript(); +} +#else +, fd_(fd), uid_(uid), pid_(pid) { UpdateDescript(); } +#endif // OHOS_BUILD_ENABLE_RUST + bool StreamSession::SendMsg(const char *buf, size_t size) const { +#ifdef OHOS_BUILD_ENABLE_RUST + return session_send_msg(&rustStreamSession_, buf, size); +#else CHKPF(buf); if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) { SEN_HILOGE("Buf size:%{public}zu", size); @@ -80,19 +94,37 @@ bool StreamSession::SendMsg(const char *buf, size_t size) const return false; } return true; +#endif // OHOS_BUILD_ENABLE_RUST } void StreamSession::Close() { +#ifdef OHOS_BUILD_ENABLE_RUST + session_close(&rustStreamSession_); + UpdateDescript(); +#else if (fd_ >= 0) { close(fd_); fd_ = -1; UpdateDescript(); } +#endif // OHOS_BUILD_ENABLE_RUST } void StreamSession::UpdateDescript() { +#ifdef OHOS_BUILD_ENABLE_RUST + std::ostringstream oss; + oss << "fd = " << rustStreamSession_.fd_ + << ", programName = " << programName_ + << ", moduleType = " << rustStreamSession_.moduleType_ + << ((rustStreamSession_.fd_ < 0) ? ", closed" : ", opened") + << ", uid = " << rustStreamSession_.uid_ + << ", pid = " << rustStreamSession_.pid_ + << ", tokenType = " << rustStreamSession_.tokenType_ + << std::endl; + descript_ = oss.str().c_str(); +#else std::ostringstream oss; oss << "fd = " << fd_ << ", programName = " << programName_ @@ -102,10 +134,20 @@ void StreamSession::UpdateDescript() << ", tokenType = " << tokenType_ << std::endl; descript_ = oss.str().c_str(); +#endif // OHOS_BUILD_ENABLE_RUST } bool StreamSession::SendMsg(const NetPacket &pkt) const { +#ifdef OHOS_BUILD_ENABLE_RUST + if (chk_rwerror(&pkt.rustStreamBuffer_)) { + SEN_HILOGE("Read and write status is error"); + return false; + } + StreamBuffer buf; + pkt.MakeData(buf); + return SendMsg(data(&buf.rustStreamBuffer_), size(&buf.rustStreamBuffer_)); +#else if (pkt.ChkRWError()) { SEN_HILOGE("Read and write status failed"); return false; @@ -113,16 +155,25 @@ bool StreamSession::SendMsg(const NetPacket &pkt) const StreamBuffer buf; pkt.MakeData(buf); return SendMsg(buf.Data(), buf.Size()); +#endif // OHOS_BUILD_ENABLE_RUST } int32_t StreamSession::GetUid() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return get_uid(&rustStreamSession_); +#else return uid_; +#endif // OHOS_BUILD_ENABLE_RUST } int32_t StreamSession::GetPid() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return get_pid(&rustStreamSession_); +#else return pid_; +#endif // OHOS_BUILD_ENABLE_RUST } SessionPtr StreamSession::GetSharedPtr() @@ -132,7 +183,11 @@ SessionPtr StreamSession::GetSharedPtr() int32_t StreamSession::GetFd() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return get_session_fd(&rustStreamSession_); +#else return fd_; +#endif // OHOS_BUILD_ENABLE_RUST } const std::string& StreamSession::GetDescript() const @@ -147,12 +202,20 @@ const std::string StreamSession::GetProgramName() const void StreamSession::SetTokenType(int32_t type) { +#ifdef OHOS_BUILD_ENABLE_RUST + set_token_type(&rustStreamSession_, type); +#else tokenType_ = type; +#endif // OHOS_BUILD_ENABLE_RUST } int32_t StreamSession::GetTokenType() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return get_token_type(&rustStreamSession_); +#else return tokenType_; +#endif // OHOS_BUILD_ENABLE_RUST } } // namespace Sensors } // namespace OHOS \ No newline at end of file diff --git a/utils/ipc/src/stream_socket.cpp b/utils/ipc/src/stream_socket.cpp index 9dd64d54..921ddfc9 100644 --- a/utils/ipc/src/stream_socket.cpp +++ b/utils/ipc/src/stream_socket.cpp @@ -21,20 +21,30 @@ namespace OHOS { namespace Sensors { +#ifndef OHOS_BUILD_ENABLE_RUST namespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "StreamSocket" }; } // namespace +#endif // OHOS_BUILD_ENABLE_RUST StreamSocket::StreamSocket() {} StreamSocket::~StreamSocket() { +#ifdef OHOS_BUILD_ENABLE_RUST + rust_close(&rustStreamSocket_); + rust_epoll_close(&rustStreamSocket_); +#else Close(); EpollClose(); +#endif // OHOS_BUILD_ENABLE_RUST } int32_t StreamSocket::EpollCreate(int32_t size) { +#ifdef OHOS_BUILD_ENABLE_RUST + return rust_epoll_create(&rustStreamSocket_, size); +#else epollFd_ = epoll_create(size); if (epollFd_ < 0) { SEN_HILOGE("Epoll create, epollFd_:%{public}d", epollFd_); @@ -42,10 +52,15 @@ int32_t StreamSocket::EpollCreate(int32_t size) SEN_HILOGI("Epoll already create, epollFd_:%{public}d", epollFd_); } return epollFd_; +#endif // OHOS_BUILD_ENABLE_RUST + } int32_t StreamSocket::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event, int32_t epollFd) { +#ifdef OHOS_BUILD_ENABLE_RUST + return rust_epoll_ctl(&rustStreamSocket_, fd, op, &event, epollFd); +#else if (fd < 0) { SEN_HILOGE("Invalid fd"); return ERROR; @@ -68,10 +83,14 @@ int32_t StreamSocket::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event ret, epollFd, op, fd, errno); } return ret; +#endif // OHOS_BUILD_ENABLE_RUST } int32_t StreamSocket::EpollWait(struct epoll_event &events, int32_t maxevents, int32_t timeout, int32_t epollFd) { +#ifdef OHOS_BUILD_ENABLE_RUST + return rust_epoll_wait(&rustStreamSocket_, &events, maxevents, timeout, epollFd); +#else if (epollFd < 0) { epollFd = epollFd_; } @@ -84,8 +103,54 @@ int32_t StreamSocket::EpollWait(struct epoll_event &events, int32_t maxevents, i SEN_HILOGE("Epoll_wait ret:%{public}d, errno:%{public}d", ret, errno); } return ret; +#endif // OHOS_BUILD_ENABLE_RUST +} + +void StreamSocket::EpollClose() +{ +#ifdef OHOS_BUILD_ENABLE_RUST + rust_epoll_close(&rustStreamSocket_); +#else + if (epollFd_ >= 0) { + close(epollFd_); + epollFd_ = -1; + } +#endif // OHOS_BUILD_ENABLE_RUST +} + +void StreamSocket::Close() +{ +#ifdef OHOS_BUILD_ENABLE_RUST + rust_close(&rustStreamSocket_); +#else + if (fd_ >= 0) { + auto rf = close(fd_); + if (rf != 0) { + SEN_HILOGE("Socket close failed, rf:%{public}d", rf); + } + } + fd_ = -1; +#endif // OHOS_BUILD_ENABLE_RUST +} + +int32_t StreamSocket::GetFd() const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return get_fd(&rustStreamSocket_); +#else + return fd_; +#endif // OHOS_BUILD_ENABLE_RUST +} +int32_t StreamSocket::GetEpollFd() const +{ +#ifdef OHOS_BUILD_ENABLE_RUST + return get_epoll_fd(&rustStreamSocket_); +#else + return epollFd_; +#endif // OHOS_BUILD_ENABLE_RUST } +#ifndef OHOS_BUILD_ENABLE_RUST void StreamSocket::OnReadPackets(CircleStreamBuffer &circBuf, StreamSocket::PacketCallBackFun callbackFun) { constexpr size_t headSize = sizeof(PackHead); @@ -127,33 +192,7 @@ void StreamSocket::OnReadPackets(CircleStreamBuffer &circBuf, StreamSocket::Pack } } } +#endif // OHOS_BUILD_ENABLE_RUST -void StreamSocket::EpollClose() -{ - if (epollFd_ >= 0) { - close(epollFd_); - epollFd_ = -1; - } -} - -void StreamSocket::Close() -{ - if (fd_ >= 0) { - auto rf = close(fd_); - if (rf != 0) { - SEN_HILOGE("Socket close failed, rf:%{public}d", rf); - } - } - fd_ = -1; -} - -int32_t StreamSocket::GetFd() const -{ - return fd_; -} -int32_t StreamSocket::GetEpollFd() const -{ - return epollFd_; -} } // namespace Sensors } // namespace OHOS \ No newline at end of file -- Gitee From c490cd07e34fd1a7d110411711a20d02d7b2bcbd Mon Sep 17 00:00:00 2001 From: baiwei Date: Mon, 29 May 2023 01:51:46 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: baiwei Change-Id: I912b78fec71643e975e3477aea5e41430104fa63 --- bundle.json | 3 +- rust/utils/socket_ipc_rust_ffi/BUILD.gn | 26 --- .../{stream_socket.rs => epoll_manager.rs} | 30 +-- .../{stream_socket => epoll_manager}/ffi.rs | 101 +++++---- rust/utils/socket_ipc_rust_ffi/src/lib.rs | 15 +- .../socket_ipc_rust_ffi/src/net_packet.rs | 14 +- .../socket_ipc_rust_ffi/src/net_packet/ffi.rs | 81 ------- .../socket_ipc_rust_ffi/src/stream_buffer.rs | 124 +++++----- .../src/stream_buffer/ffi.rs | 213 ++++++++++++------ .../socket_ipc_rust_ffi/src/stream_session.rs | 59 +++-- .../src/stream_session/ffi.rs | 120 +++++++--- rust/utils/socket_ipc_rust_ffi/test/main.rs | 135 ----------- services/sensor/BUILD.gn | 2 +- services/sensor/src/sensor_power_policy.cpp | 2 +- utils/ipc/include/rust_binding.h | 123 ++++------ utils/ipc/include/stream_buffer.h | 11 +- utils/ipc/include/stream_session.h | 3 +- utils/ipc/include/stream_socket.h | 17 +- utils/ipc/src/circle_stream_buffer.cpp | 6 +- utils/ipc/src/net_packet.cpp | 12 +- utils/ipc/src/stream_buffer.cpp | 32 ++- utils/ipc/src/stream_session.cpp | 44 ++-- utils/ipc/src/stream_socket.cpp | 18 +- 23 files changed, 568 insertions(+), 623 deletions(-) rename rust/utils/socket_ipc_rust_ffi/src/{stream_socket.rs => epoll_manager.rs} (89%) rename rust/utils/socket_ipc_rust_ffi/src/{stream_socket => epoll_manager}/ffi.rs (42%) delete mode 100644 rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs delete mode 100644 rust/utils/socket_ipc_rust_ffi/test/main.rs diff --git a/bundle.json b/bundle.json index 0a269b64..013898ca 100644 --- a/bundle.json +++ b/bundle.json @@ -62,8 +62,7 @@ "test": [ "//base/sensors/sensor/interfaces/plugin/test/unittest:unittest", "//base/sensors/sensor/interfaces/native/test/fuzztest:fuzztest", - "//base/sensors/sensor/interfaces/native/test:unittest", - "//base/sensors/sensor/rust/utils/socket_ipc_rust_ffi:unittest" + "//base/sensors/sensor/interfaces/native/test:unittest" ] } } diff --git a/rust/utils/socket_ipc_rust_ffi/BUILD.gn b/rust/utils/socket_ipc_rust_ffi/BUILD.gn index 0d56aefa..aa00862d 100644 --- a/rust/utils/socket_ipc_rust_ffi/BUILD.gn +++ b/rust/utils/socket_ipc_rust_ffi/BUILD.gn @@ -29,29 +29,3 @@ ohos_rust_shared_ffi("sensor_rust_util_ffi") { part_name = "sensor" subsystem_name = "sensors" } - -ohos_rust_shared_library("sensor_rust_util") { - sources = [ "src/lib.rs" ] - - external_deps = [ - "c_utils:utils", - "hiviewdfx_hilog_native:hilog_rust", - "hiviewdfx_hilog_native:libhilog", - ] - - crate_name = "sensor_rust_util" - crate_type = "dylib" - install_images = [ system_base_dir ] - - part_name = "sensor" - subsystem_name = "sensors" -} - -ohos_executable("test_sensor_pkt") { - sources = [ "test/main.rs" ] - deps = [ ":sensor_rust_util" ] -} - -group("unittest") { - deps = [ ":test_sensor_pkt" ] -} diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs similarity index 89% rename from rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs rename to rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs index 64d91e22..d5e762a7 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_socket.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs @@ -17,29 +17,31 @@ pub mod ffi; use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; use std::ptr; -use libc::{c_int, c_uint}; +use libc::c_int; use std::ffi::{CString, c_char}; +use std::thread::sleep; +use std::time::Duration; const ONCE_PROCESS_NETPACKET_LIMIT: i32 = 100; const MAX_PACKET_BUF_SIZE: usize = 256; -const SEND_RETRY_SLEEP_TIME: c_uint = 10000; +const SEND_RETRY_SLEEP_TIME: u64 = 10000; const SEND_RETRY_LIMIT: i32 = 32; const LOG_LABEL: HiLogLabel = HiLogLabel { log_type: LogType::LogCore, domain: 0xD002220, - tag: "StreamSocket" + tag: "EpollManager" }; -/// struct StreamSocket +/// struct EpollManager #[repr(C)] -pub struct StreamSocket { +pub struct EpollManager { /// socket_fd pub socket_fd: i32, /// epoll_fd pub epoll_fd: i32, } -impl Default for StreamSocket { +impl Default for EpollManager { fn default() -> Self { Self { socket_fd: -1, @@ -48,7 +50,7 @@ impl Default for StreamSocket { } } -impl StreamSocket { +impl EpollManager { /// return const referance of self /// /// # Safety @@ -135,9 +137,9 @@ impl StreamSocket { pub fn socket_close(&mut self) { if self.socket_fd >= 0 { unsafe { - let rf = libc::close(self.socket_fd as c_int); - if rf > 0 { - error!(LOG_LABEL, "Socket close failed rf:{}", rf); + let res = libc::close(self.socket_fd as c_int); + if res > 0 { + error!(LOG_LABEL, "Socket close failed res:{}", res); } } self.socket_fd = -1; @@ -179,19 +181,17 @@ impl StreamSocket { error!(LOG_LABEL, "Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:{}", errno); continue; } - error!(LOG_LABEL, "Send return failed,error:{} fd:{}", errno, self.socket_fd); + error!(LOG_LABEL, "Send return failed,error:{}, fd:{}", errno, self.socket_fd); return false; } idx += count as usize; rem_size -= count as usize; if rem_size > 0 { - unsafe { - libc::usleep(SEND_RETRY_SLEEP_TIME); - } + sleep(Duration::from_micros(SEND_RETRY_SLEEP_TIME)); } } if retry_count >= SEND_RETRY_LIMIT || rem_size != 0 { - error!(LOG_LABEL, "Send too many times:{}/{},size:{}/{} fd:{}", + error!(LOG_LABEL, "Send too many times: {}/{}, size: {}/{}, fd: {}", retry_count, SEND_RETRY_LIMIT, idx, buf_size, self.socket_fd); return false; } diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs similarity index 42% rename from rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs rename to rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs index 68f18065..6374bb5a 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_socket/ffi.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs @@ -16,27 +16,44 @@ use super::*; use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; use crate::error::SocketStatusCode; +use crate::epoll_manager::EpollManager; +use std::mem::drop; const LOG_LABEL: HiLogLabel = HiLogLabel { log_type: LogType::LogCore, domain: 0xD002220, tag: "stream_socket_ffi" }; +/// create unique_ptr of stream_socket for C++ +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSocketCreate() -> *mut EpollManager { + let epoll_manager: Box:: = Box::default(); + Box::into_raw(epoll_manager) +} +/// drop unique_ptr of stream_socket for C++ +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSocketDelete(raw: *mut EpollManager) { + if !raw.is_null() { + drop(Box::from_raw(raw)); + } +} /// Get Fd /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_fd(object: *const StreamSocket) -> i32 { - info!(LOG_LABEL, "enter get_fd"); - // 等价于 - // let obj = object.as_ref() ; - // match obj { - // Some(obj) => obj.fd(), - // None => return -1; - // } - if let Some(obj) = StreamSocket::as_ref(object) { +pub unsafe extern "C" fn StreamSocketGetFd(object: *const EpollManager) -> i32 { + info!(LOG_LABEL, "enter StreamSocketGetFd"); + if let Some(obj) = EpollManager::as_ref(object) { obj.socket_fd() } else { SocketStatusCode::FdFail.into() @@ -49,9 +66,9 @@ pub unsafe extern "C" fn get_fd(object: *const StreamSocket) -> i32 { /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_epoll_fd(object: *const StreamSocket) -> i32 { - info!(LOG_LABEL, "enter get_epoll_fd"); - if let Some(obj) = StreamSocket::as_ref(object) { +pub unsafe extern "C" fn StreamSocketGetEpollFd(object: *const EpollManager) -> i32 { + info!(LOG_LABEL, "enter StreamSocketGetEpollFd"); + if let Some(obj) = EpollManager::as_ref(object) { obj.epoll_fd() } else { SocketStatusCode::EpollFdFail.into() @@ -64,10 +81,9 @@ pub unsafe extern "C" fn get_epoll_fd(object: *const StreamSocket) -> i32 { /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn rust_epoll_create(object: *mut StreamSocket, size: i32) -> i32 { - info!(LOG_LABEL, "enter rust_epoll_create"); - - if let Some(obj) = StreamSocket::as_mut(object) { +pub unsafe extern "C" fn StreamSocketEpollCreate(object: *mut EpollManager, size: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSocketEpollCreate"); + if let Some(obj) = EpollManager::as_mut(object) { obj.create_epoll_fd(size); obj.epoll_fd() } else { @@ -76,16 +92,16 @@ pub unsafe extern "C" fn rust_epoll_create(object: *mut StreamSocket, size: i32) } -/// rust_epoll_ctl +/// StreamSocketEpollCtl /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn rust_epoll_ctl(object: *const StreamSocket, fd: i32, op: i32, +pub unsafe extern "C" fn StreamSocketEpollCtl(object: *const EpollManager, fd: i32, op: i32, event: *mut libc::epoll_event, epoll_fd: i32) -> i32 { - info!(LOG_LABEL, "enter rust_epoll_ctl"); - if let Some(obj) = StreamSocket::as_ref(object) { + info!(LOG_LABEL, "enter StreamSocketEpollCtl"); + if let Some(obj) = EpollManager::as_ref(object) { if fd < 0 { error!(LOG_LABEL, "Invalid fd"); return -1 @@ -100,22 +116,22 @@ pub unsafe extern "C" fn rust_epoll_ctl(object: *const StreamSocket, fd: i32, op } else { epoll_fd }; - StreamSocket::epoll_ctl(fd, op, event, epoll_fd) + EpollManager::epoll_ctl(fd, op, event, epoll_fd) } else { SocketStatusCode::EpollCtlFail.into() } } -/// rust_epoll_wait +/// StreamSocketEpollWait /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn rust_epoll_wait( - object: *const StreamSocket, events: *mut libc::epoll_event, maxevents: i32, timeout: i32, epoll_fd: i32) -> i32 { - info!(LOG_LABEL, "enter rust_epoll_wait"); - if let Some(obj) = StreamSocket::as_ref(object) { +pub unsafe extern "C" fn StreamSocketEpollWait( + object: *const EpollManager, events: *mut libc::epoll_event, maxevents: i32, timeout: i32, epoll_fd: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSocketEpollWait"); + if let Some(obj) = EpollManager::as_ref(object) { let epoll_fd = if epoll_fd < 0 { if obj.is_valid_epoll() { @@ -126,54 +142,41 @@ pub unsafe extern "C" fn rust_epoll_wait( } else { epoll_fd }; - StreamSocket::epoll_wait(events, maxevents, timeout, epoll_fd) + EpollManager::epoll_wait(events, maxevents, timeout, epoll_fd) } else { SocketStatusCode::EpollWaitFail.into() } } -/// rust_epoll_close +/// StreamSocketEpollClose /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn rust_epoll_close(object: *mut StreamSocket) -> i32 { - info!(LOG_LABEL, "enter rust_epoll_close"); - if let Some(obj) = StreamSocket::as_mut(object) { +pub unsafe extern "C" fn StreamSocketEpollClose(object: *mut EpollManager) -> i32 { + info!(LOG_LABEL, "enter StreamSocketEpollClose"); + if let Some(obj) = EpollManager::as_mut(object) { obj.epoll_close(); SocketStatusCode::Ok.into() } else { SocketStatusCode::EpollCloseFail.into() } } -/// rust_close +/// StreamSocketClose /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn rust_close(object: *mut StreamSocket) -> i32 { - info!(LOG_LABEL, "enter rust_close"); - if let Some(obj) = StreamSocket::as_mut(object) { +pub unsafe extern "C" fn StreamSocketClose(object: *mut EpollManager) -> i32 { + info!(LOG_LABEL, "enter StreamSocketClose"); + if let Some(obj) = EpollManager::as_mut(object) { obj.socket_close(); SocketStatusCode::Ok.into() } else { SocketStatusCode::SocketCloseFail.into() } } -/// send_msg_buf_size -/// -/// # Safety -/// -/// object must be valid -#[no_mangle] -pub unsafe extern "C" fn send_msg_buf_size(object: *const StreamSocket, buf: *const c_char, size: usize) -> bool { - info!(LOG_LABEL, "enter send_msg_buf_size"); - if let Some(obj) = StreamSocket::as_ref(object) { - obj.send_msg(buf, size) - } else { - false - } -} + diff --git a/rust/utils/socket_ipc_rust_ffi/src/lib.rs b/rust/utils/socket_ipc_rust_ffi/src/lib.rs index f0c1b9ff..890fb825 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/lib.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/lib.rs @@ -18,16 +18,11 @@ #![allow(dead_code)] extern crate libc; -/// mod stream socket -pub mod stream_socket; -/// mod stream buffer -pub mod stream_buffer; -/// mod stream session -pub mod stream_session; -/// mod net packet -pub mod net_packet; -/// mod binding for binding extern C interface -pub mod binding; +mod epoll_manager; +mod stream_buffer; +mod stream_session; +mod net_packet; +mod binding; mod error; /// annotation pub type Result = std::result::Result; diff --git a/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs b/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs index 5fadf1fd..7fe03051 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs @@ -12,9 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/// C++ call function -pub mod ffi; + use std::ffi::{CString, c_char}; use hilog_rust::{hilog, error, HiLogLabel, LogType}; use std::mem::size_of; @@ -33,7 +31,7 @@ pub struct PackHead { /// NetPacket type pub id_msg: MessageId, /// SufferBuffer size - pub size: i32, + pub size: usize, } /// NetPacket type @@ -91,7 +89,7 @@ pub enum MessageId { pub struct NetPacket { /// NetPacket head pub msg_id: MessageId, - /// NetPacket streambuffer + /// NetPacket stream buffer pub stream_buffer: StreamBuffer, } @@ -138,8 +136,8 @@ impl NetPacket { self.stream_buffer.size() } /// get_packet_length - pub fn get_packet_length(&self) -> i32 { - size_of::() as i32 + self.stream_buffer.w_pos + pub fn get_packet_length(&self) -> usize { + size_of::() + self.stream_buffer.w_pos } /// get_data pub fn get_data(&self) -> *const c_char { @@ -157,7 +155,7 @@ impl NetPacket { }; buf.write(head); if self.stream_buffer.w_pos > 0 && !buf.write_char_usize(&self.stream_buffer.sz_buff[0] as *const c_char, - self.stream_buffer.w_pos as usize) { + self.stream_buffer.w_pos) { error!(LOG_LABEL, "Write data to stream failed, errCode:{}", STREAM_BUF_WRITE_FAIL); } } diff --git a/rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs deleted file mode 100644 index b896fd5e..00000000 --- a/rust/utils/socket_ipc_rust_ffi/src/net_packet/ffi.rs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use super::*; -use hilog_rust::{info, hilog, HiLogLabel, LogType}; -use std::ffi::CString; -use crate::error::NetPacketStatusCode; -const LOG_LABEL: HiLogLabel = HiLogLabel { - log_type: LogType::LogCore, - domain: 0xD002220, - tag: "net_packet_ffi" -}; - -/// Get size -/// -/// # Safety -/// -/// object must be valid -#[no_mangle] -pub unsafe extern "C" fn get_size(object: *const NetPacket) -> usize { - info!(LOG_LABEL, "enter get_size"); - if let Some(obj) = NetPacket::as_ref(object) { - obj.size() - } else { - 0 - } -} -/// Get packet length -/// -/// # Safety -/// -/// object must be valid -#[no_mangle] -pub unsafe extern "C" fn get_packet_length(object: *const NetPacket) -> i32 { - info!(LOG_LABEL, "enter get_packet_length"); - if let Some(obj) = NetPacket::as_ref(object) { - obj.get_packet_length() - } else { - NetPacketStatusCode::PacketLengthFail.into() - } -} -/// Get data -/// -/// # Safety -/// -/// object must be valid -#[no_mangle] -pub unsafe extern "C" fn get_data(object: *const NetPacket) -> *const c_char { - info!(LOG_LABEL, "enter get_data"); - if let Some(obj) = NetPacket::as_ref(object) { - obj.get_data() - } else { - std::ptr::null() - } -} -/// Get msg_id -/// -/// # Safety -/// -/// object must be valid -#[no_mangle] -pub unsafe extern "C" fn get_msg_id(object: *const NetPacket) -> MessageId { - info!(LOG_LABEL, "enter get_msg_id"); - if let Some(obj) = NetPacket::as_ref(object) { - obj.get_msg_id() - } else { - MessageId::Invalid - } -} diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs index 28d63e78..11e47635 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs @@ -73,13 +73,13 @@ pub struct StreamBuffer { /// error status of read or write pub rw_error_status: ErrorStatus, /// read count - pub r_count: i32, + pub r_count: usize, /// write count - pub w_count: i32, + pub w_count: usize, /// read position - pub r_pos: i32, + pub r_pos: usize, /// write position - pub w_pos: i32, + pub w_pos: usize, /// buffer of read or write pub sz_buff: [c_char; MAX_STREAM_BUF_SIZE + 1], } @@ -144,9 +144,9 @@ impl StreamBuffer { } } - fn seek_read_pos(&mut self, n: i32) -> bool { - let pos: i32 = self.r_pos + n; - if pos < 0 || pos > self.w_pos { + fn seek_read_pos(&mut self, n: usize) -> bool { + let pos: usize = self.r_pos + n; + if pos > self.w_pos { error!(LOG_LABEL, "The position in the calculation is not as expected. pos:{} [0, {}]", pos, self.w_pos); return false; @@ -157,10 +157,10 @@ impl StreamBuffer { /// write buffer pub fn write_buf(&self) -> *const c_char { info!(LOG_LABEL, "enter write_buf"); - &self.sz_buff[self.w_pos as usize] as *const c_char + &self.sz_buff[self.w_pos] as *const c_char } /// unread size - pub fn unread_size(&self) -> i32 { + pub fn unread_size(&self) -> usize { if self.w_pos <= self.r_pos { 0 } else { @@ -184,17 +184,17 @@ impl StreamBuffer { } /// size function pub fn size(&self) -> usize { - self.w_pos as usize + self.w_pos } /// check error status of read or write pub fn chk_rwerror(&self) -> bool { self.rw_error_status != ErrorStatus::Ok } - fn get_available_buf_size(&self) -> i32 { - if self.w_pos >= MAX_STREAM_BUF_SIZE as i32 { + fn get_available_buf_size(&self) -> usize { + if self.w_pos >= MAX_STREAM_BUF_SIZE { 0 } else { - MAX_STREAM_BUF_SIZE as i32 - self.w_pos + MAX_STREAM_BUF_SIZE - self.w_pos } } fn get_error_status_remark(&self) -> *const c_char { @@ -207,7 +207,7 @@ impl StreamBuffer { s.as_ptr() } fn read_buf(&self) -> *const c_char { - &(self.sz_buff[self.r_pos as usize]) as *const c_char + &(self.sz_buff[self.r_pos]) as *const c_char } /// write buffer pub fn write_char_usize(&mut self, buf: *const c_char, size: usize) -> bool { @@ -224,7 +224,7 @@ impl StreamBuffer { self.rw_error_status = ErrorStatus::Write; return false; } - if (self.w_pos + size as i32) > MAX_STREAM_BUF_SIZE as i32 { + if (self.w_pos + size) > MAX_STREAM_BUF_SIZE { error!(LOG_LABEL, "The write length exceeds buffer. wIdx:{} size:{} maxBufSize:{} errCode:{}", self.w_pos, size, MAX_STREAM_BUF_SIZE, MEM_OUT_OF_BOUNDS); self.rw_error_status = ErrorStatus::Write; @@ -232,20 +232,20 @@ impl StreamBuffer { } unsafe { let pointer = &(self.sz_buff[0]) as *const c_char; - let ret = binding::memcpy_s(pointer.add(self.w_pos as usize) as *mut libc::c_void, - self.get_available_buf_size() as usize, buf as *mut libc::c_void, size); + let ret = binding::memcpy_s(pointer.add(self.w_pos) as *mut libc::c_void, + self.get_available_buf_size(), buf as *mut libc::c_void, size); if ret != 0 { error!(LOG_LABEL, "Failed to call memcpy_s. ret:{}", ret); self.rw_error_status = ErrorStatus::Write; return false; } } - self.w_pos += size as i32; + self.w_pos += size; self.w_count += 1; true } fn check_write(&mut self, size: usize) -> bool { - let buffer_size = size as i32; + let buffer_size = size; let mut avail_size = self.get_available_buf_size(); if buffer_size > avail_size && self.r_pos > 0 { self.copy_data_to_begin(); @@ -254,10 +254,10 @@ impl StreamBuffer { avail_size >= buffer_size } fn copy_data_to_begin(&mut self) { - let unread_size: i32 = self.unread_size(); + let unread_size = self.unread_size(); if unread_size > 0 && self.r_pos > 0 { for (index, value) in (self.r_pos..=self.w_pos).enumerate() { - self.sz_buff[index] = self.sz_buff[value as usize]; + self.sz_buff[index] = self.sz_buff[value]; } } debug!(LOG_LABEL, "unread_size:{} rPos:{} wPos:{}", unread_size, self.r_pos, self.w_pos); @@ -279,7 +279,7 @@ impl StreamBuffer { self.rw_error_status = ErrorStatus::Read; return false; } - if (self.r_pos + size as i32) > self.w_pos { + if (self.r_pos + size) > self.w_pos { error!(LOG_LABEL, "Memory out of bounds on read... errCode:{}", MEM_OUT_OF_BOUNDS); self.rw_error_status = ErrorStatus::Read; return false; @@ -292,7 +292,7 @@ impl StreamBuffer { return false; } } - self.r_pos += size as i32; + self.r_pos += size; self.r_count += 1; true } @@ -313,21 +313,21 @@ impl StreamBuffer { /// call unsafe function pub unsafe fn read_server_packets(&mut self, stream_server: *const CStreamServer, fd: i32, callback_fun: ServerPacketCallBackFun) { - const HEAD_SIZE: i32 = size_of::() as i32; - for _i in 0.. ONCE_PROCESS_NETPACKET_LIMIT { - let unread_size: i32 = self.unread_size(); + const HEAD_SIZE: usize = size_of::(); + for _i in 0..ONCE_PROCESS_NETPACKET_LIMIT { + let unread_size = self.unread_size(); if unread_size < HEAD_SIZE { break; } - let data_size :i32 = unread_size - HEAD_SIZE; + let data_size = unread_size - HEAD_SIZE; let buf: *const c_char = self.read_buf(); if buf.is_null() { - error!(LOG_LABEL, "CHKPB(buf) is null, skip then break"); + error!(LOG_LABEL, "buf is null, skip then break"); break; } let head: *const PackHead = buf as *const PackHead; if head.is_null() { - error!(LOG_LABEL, "CHKPB(head) is null, skip then break"); + error!(LOG_LABEL, "head is null, skip then break"); break; } let size; @@ -336,9 +336,9 @@ impl StreamBuffer { size = (*head).size; id_msg = (*head).id_msg; } - if !(0..=MAX_PACKET_BUF_SIZE).contains(&(size as usize)) { + if !(0..=MAX_PACKET_BUF_SIZE).contains(&size) { error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ - The buffer will be reset. (*head).size:{}, unreadSize:{}", size, unread_size); + The buffer will be reset. size:{}, unreadSize:{}", size, unread_size); self.reset(); break; } @@ -351,7 +351,7 @@ impl StreamBuffer { }; unsafe { if size > 0 && - !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE as usize) as *const c_char, size as usize) { + !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE) as *const c_char, size) { error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ messageid:{}, size:{}", id_msg as i32, size); break; @@ -378,21 +378,21 @@ impl StreamBuffer { /// /// call unsafe function pub unsafe fn read_client_packets(&mut self, client: *const CClient, callback_fun: ClientPacketCallBackFun) { - const HEAD_SIZE: i32 = size_of::() as i32; - for _i in 0.. ONCE_PROCESS_NETPACKET_LIMIT { - let unread_size: i32 = self.unread_size(); + const HEAD_SIZE: usize = size_of::(); + for _i in 0..ONCE_PROCESS_NETPACKET_LIMIT { + let unread_size = self.unread_size(); if unread_size < HEAD_SIZE { break; } - let data_size :i32 = unread_size - HEAD_SIZE; + let data_size = unread_size - HEAD_SIZE; let buf: *const c_char = self.read_buf(); if buf.is_null() { - error!(LOG_LABEL, "CHKPB(buf) is null, skip then break"); + error!(LOG_LABEL, "buf is null, skip then break"); break; } let head: *const PackHead = buf as *const PackHead; if head.is_null() { - error!(LOG_LABEL, "CHKPB(head) is null, skip then break"); + error!(LOG_LABEL, "head is null, skip then break"); break; } let size; @@ -401,9 +401,9 @@ impl StreamBuffer { size = (*head).size; id_msg = (*head).id_msg; } - if !(0..=MAX_PACKET_BUF_SIZE).contains(&(size as usize)) { + if !(0..=MAX_PACKET_BUF_SIZE).contains(&size) { error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ - The buffer will be reset. (*head).size:{}, unreadSize:{}", size, unread_size); + The buffer will be reset. size:{}, unreadSize:{}", size, unread_size); self.reset(); break; } @@ -416,7 +416,7 @@ impl StreamBuffer { }; unsafe { if size > 0 && - !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE as usize) as *const c_char, size as usize) { + !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE) as *const c_char, size) { error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ messageid:{}, size:{}", id_msg as i32, size); break; @@ -443,21 +443,21 @@ impl StreamBuffer { /// /// call unsafe function pub unsafe fn read_packets(&mut self, callback_fun: ReadPacketCallBackFun) { - const HEAD_SIZE: i32 = size_of::() as i32; - for _i in 0.. ONCE_PROCESS_NETPACKET_LIMIT { - let unread_size: i32 = self.unread_size(); + const HEAD_SIZE: usize = size_of::(); + for _i in 0..ONCE_PROCESS_NETPACKET_LIMIT { + let unread_size = self.unread_size(); if unread_size < HEAD_SIZE { break; } - let data_size :i32 = unread_size - HEAD_SIZE; + let data_size = unread_size - HEAD_SIZE; let buf: *const c_char = self.read_buf(); if buf.is_null() { - error!(LOG_LABEL, "CHKPB(buf) is null, skip then break"); + error!(LOG_LABEL, "buf is null, skip then break"); break; } let head: *const PackHead = buf as *const PackHead; if head.is_null() { - error!(LOG_LABEL, "CHKPB(head) is null, skip then break"); + error!(LOG_LABEL, "head is null, skip then break"); break; } let size; @@ -466,9 +466,9 @@ impl StreamBuffer { size = (*head).size; id_msg = (*head).id_msg; } - if !(0..=MAX_PACKET_BUF_SIZE).contains(&(size as usize)) { + if !(0..=MAX_PACKET_BUF_SIZE).contains(&size) { error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ - The buffer will be reset. (*head).size:{}, unreadSize:{}", size, unread_size); + The buffer will be reset. size:{}, unreadSize:{}", size, unread_size); self.reset(); break; } @@ -481,7 +481,7 @@ impl StreamBuffer { }; unsafe { if size > 0 && - !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE as usize) as *const c_char, size as usize) { + !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE) as *const c_char, size) { error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ messageid:{}, size:{}", id_msg as i32, size); break; @@ -500,8 +500,26 @@ impl StreamBuffer { } } } - - - + fn r_count(&self) -> usize { + self.r_count + } + fn w_count(&self) -> usize { + self.w_count + } + fn w_pos(&self) -> usize { + self.w_pos + } + fn r_pos(&self) -> usize { + self.r_pos + } + fn sz_buff(&self) -> *const c_char { + &self.sz_buff[0] as *const c_char + } + fn set_rw_error_status(&mut self, rw_error_status: ErrorStatus) { + self.rw_error_status = rw_error_status + } + fn set_r_pos(&mut self, r_pos: usize) { + self.r_pos = r_pos + } } diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs index 4ef33f5a..e4b38a37 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs @@ -21,13 +21,34 @@ const LOG_LABEL: HiLogLabel = HiLogLabel { domain: 0xD002220, tag: "stream_buffer_ffi" }; +/// create unique_ptr of stream_buffer for C++ +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferCreate() -> *mut StreamBuffer { + let stream_buffer: Box:: = Box::default(); + Box::into_raw(stream_buffer) +} +/// drop unique_ptr of stream_buffer for C++ +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferDelete(raw: *mut StreamBuffer) { + if !raw.is_null() { + drop(Box::from_raw(raw)); + } +} /// data /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn data(object: *const StreamBuffer) -> *const c_char { +pub unsafe extern "C" fn StreamBufferData(object: *const StreamBuffer) -> *const c_char { info!(LOG_LABEL, "enter data"); if let Some(obj) = StreamBuffer::as_ref(object) { obj.data() @@ -41,7 +62,7 @@ pub unsafe extern "C" fn data(object: *const StreamBuffer) -> *const c_char { /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn size(object: *const StreamBuffer) -> usize { +pub unsafe extern "C" fn StreamBufferSize(object: *const StreamBuffer) -> usize { info!(LOG_LABEL, "enter size"); if let Some(obj) = StreamBuffer::as_ref(object) { obj.size() @@ -49,14 +70,14 @@ pub unsafe extern "C" fn size(object: *const StreamBuffer) -> usize { 0 } } -/// reset +/// StreamBufferReset /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn reset(object: *mut StreamBuffer) -> i32 { - info!(LOG_LABEL, "enter reset"); +pub unsafe extern "C" fn StreamBufferReset(object: *mut StreamBuffer) -> i32 { + info!(LOG_LABEL, "enter StreamBufferReset"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.reset(); BufferStatusCode::Ok.into() @@ -64,13 +85,13 @@ pub unsafe extern "C" fn reset(object: *mut StreamBuffer) -> i32 { BufferStatusCode::ResetFail.into() } } -/// clean +/// StreamBufferClean /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn clean(object: *mut StreamBuffer) -> i32 { +pub unsafe extern "C" fn StreamBufferClean(object: *mut StreamBuffer) -> i32 { info!(LOG_LABEL, "enter clean"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.clean(); @@ -79,45 +100,16 @@ pub unsafe extern "C" fn clean(object: *mut StreamBuffer) -> i32 { BufferStatusCode::CleanFail.into() } } -/// unread_size +/// StreamBufferWrite /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn unread_size(object: *mut StreamBuffer) -> i32 { - info!(LOG_LABEL, "enter unread_size"); - if let Some(obj) = StreamBuffer::as_mut(object) { - obj.unread_size() - } else { - BufferStatusCode::UnreadSizeFail.into() - } -} -/// is_empty -/// -/// # Safety -/// -/// object is valid -#[no_mangle] -pub unsafe extern "C" fn is_empty(object: *const StreamBuffer) -> bool { - info!(LOG_LABEL, "enter is_empty"); - if let Some(obj) = StreamBuffer::as_ref(object) { - obj.is_empty() - } else { - false - } -} -/// write_streambuffer -/// -/// # Safety -/// -/// object is valid -#[no_mangle] -pub unsafe extern "C" fn write_streambuffer(object: *mut StreamBuffer, buf: *const StreamBuffer) -> bool { - info!(LOG_LABEL, "enter write_streambuffer"); +pub unsafe extern "C" fn StreamBufferWrite(object: *mut StreamBuffer, buf: *const StreamBuffer) -> bool { + info!(LOG_LABEL, "enter StreamBufferWrite"); if let Some(obj) = StreamBuffer::as_mut(object) { if let Some(buffer) = StreamBuffer::as_ref(buf) { - obj.write_streambuffer(buffer) } else { false @@ -126,14 +118,14 @@ pub unsafe extern "C" fn write_streambuffer(object: *mut StreamBuffer, buf: *con false } } -/// read_streambuffer +/// StreamBufferRead /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn read_streambuffer(object: *const StreamBuffer, buf: *mut StreamBuffer) -> bool { - info!(LOG_LABEL, "enter read_streambuffer"); +pub unsafe extern "C" fn StreamBufferRead(object: *const StreamBuffer, buf: *mut StreamBuffer) -> bool { + info!(LOG_LABEL, "enter StreamBufferRead"); if let Some(obj) = StreamBuffer::as_ref(object) { if let Some(buffer) = StreamBuffer::as_mut(buf) { obj.read_streambuffer(buffer) @@ -144,69 +136,69 @@ pub unsafe extern "C" fn read_streambuffer(object: *const StreamBuffer, buf: *mu false } } -/// chk_rwerror +/// StreamBufferChkRWError /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn chk_rwerror(object: *const StreamBuffer) -> bool { +pub unsafe extern "C" fn StreamBufferChkRWError(object: *const StreamBuffer) -> bool { if let Some(obj) = StreamBuffer::as_ref(object) { obj.chk_rwerror() } else { false } } -/// get_error_status_remark +/// StreamBufferGetErrorStatusRemark /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn get_error_status_remark(object: *const StreamBuffer) -> *const c_char { - info!(LOG_LABEL, "enter get_error_status_remark"); +pub unsafe extern "C" fn StreamBufferGetErrorStatusRemark(object: *const StreamBuffer) -> *const c_char { + info!(LOG_LABEL, "enter StreamBufferGetErrorStatusRemark"); if let Some(obj) = StreamBuffer::as_ref(object) { obj.get_error_status_remark() } else { std::ptr::null() } } -/// write_char_usize +/// StreamBufferWriteChar /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn write_char_usize(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { - info!(LOG_LABEL, "enter write_char_usize"); +pub unsafe extern "C" fn StreamBufferWriteChar(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter StreamBufferWriteChar"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.write_char_usize(buf, size) } else { false } } -/// check_write +/// StreamBufferCheckWrite /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn check_write(object: *mut StreamBuffer, size: usize) -> bool { - info!(LOG_LABEL, "enter check_write"); +pub unsafe extern "C" fn StreamBufferCheckWrite(object: *mut StreamBuffer, size: usize) -> bool { + info!(LOG_LABEL, "enter StreamBufferCheckWrite"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.check_write(size) } else { false } } -/// copy_data_to_begin +/// CircleStreamBufferCopyDataToBegin /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn copy_data_to_begin(object: *mut StreamBuffer) -> i32 { - info!(LOG_LABEL, "enter copy_data_to_begin"); +pub unsafe extern "C" fn CircleStreamBufferCopyDataToBegin(object: *mut StreamBuffer) -> i32 { + info!(LOG_LABEL, "enter CircleStreamBufferCopyDataToBegin"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.copy_data_to_begin(); BufferStatusCode::Ok.into() @@ -214,28 +206,28 @@ pub unsafe extern "C" fn copy_data_to_begin(object: *mut StreamBuffer) -> i32 { BufferStatusCode::CopyDataToBeginFail.into() } } -/// read_char_usize +/// StreamBufferReadChar /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn read_char_usize(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { - info!(LOG_LABEL, "enter read_char_usize"); +pub unsafe extern "C" fn StreamBufferReadChar(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter StreamBufferReadChar"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.read_char_usize(buf, size) } else { false } } -/// circle_write +/// CircleStreamBufferWrite /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn circle_write(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { - info!(LOG_LABEL, "enter circle_write"); +pub unsafe extern "C" fn CircleStreamBufferWrite(object: *mut StreamBuffer, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter CircleStreamBufferWrite"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.circle_write(buf, size) } else { @@ -274,17 +266,110 @@ pub unsafe extern "C" fn read_client_packets(object: *mut StreamBuffer, stream_c BufferStatusCode::ReadClientPacketsFail.into() } } -/// read_buf +/// StreamBufferReadBuf /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn read_buf(object: *const StreamBuffer) -> *const c_char { +pub unsafe extern "C" fn StreamBufferReadBuf(object: *const StreamBuffer) -> *const c_char { if let Some(obj) = StreamBuffer::as_ref(object) { obj.read_buf() } else { std::ptr::null() } } +/// StreamBufferGetRcount +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferGetRcount(object: *const StreamBuffer) -> i32 { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.r_count() as i32 + } else { + BufferStatusCode::Fail.into() + } +} +/// StreamBufferGetWcount +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferGetWcount(object: *const StreamBuffer) -> i32 { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.w_count() as i32 + } else { + BufferStatusCode::Fail.into() + } +} +/// StreamBufferGetWpos +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferGetWpos(object: *const StreamBuffer) -> i32 { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.w_pos() as i32 + } else { + BufferStatusCode::Fail.into() + } +} +/// StreamBufferGetRpos +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferGetRpos(object: *const StreamBuffer) -> i32 { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.r_pos() as i32 + } else { + BufferStatusCode::Fail.into() + } +} +/// StreamBufferGetSzBuff +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferGetSzBuff(object: *const StreamBuffer) -> *const c_char { + if let Some(obj) = StreamBuffer::as_ref(object) { + obj.sz_buff() + } else { + std::ptr::null() + } +} +/// StreamBufferSetRwErrStatus +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferSetRwErrStatus(object: *mut StreamBuffer, rw_error_status: ErrorStatus) -> i32 { + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.set_rw_error_status(rw_error_status); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::Fail.into() + } +} +/// StreamBufferSetRpos +/// +/// # Safety +/// +/// object is valid +#[no_mangle] +pub unsafe extern "C" fn StreamBufferSetRpos(object: *mut StreamBuffer, r_pos: i32) -> i32 { + if let Some(obj) = StreamBuffer::as_mut(object) { + obj.set_r_pos(r_pos as usize); + BufferStatusCode::Ok.into() + } else { + BufferStatusCode::Fail.into() + } +} diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs index b0158cf0..b7cb4e7f 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs @@ -16,8 +16,10 @@ /// provide C interface to C++ for calling pub mod ffi; use hilog_rust::{debug, error, hilog, HiLogLabel, LogType}; -use libc::{int32_t, int64_t, c_int, c_uint}; +use libc::{int32_t, int64_t, c_int}; use std::ffi::{CString, c_char}; +use std::thread::sleep; +use std::time::Duration; use crate::net_packet::NetPacket; use crate::stream_buffer::StreamBuffer; const LOG_LABEL: HiLogLabel = HiLogLabel { @@ -27,7 +29,8 @@ const LOG_LABEL: HiLogLabel = HiLogLabel { }; const MAX_PACKET_BUF_SIZE: usize = 256; const SEND_RETRY_LIMIT: i32 = 32; -const SEND_RETRY_SLEEP_TIME: c_uint = 10000; +const SEND_RETRY_SLEEP_TIME: u64 = 10000; + #[repr(C)] struct EventTime { id: int32_t, @@ -50,6 +53,18 @@ pub struct StreamSession { pub token_type: i32, } +impl Default for StreamSession { + fn default() -> Self { + Self { + module_type: -1, + fd: -1, + uid: -1, + pid: -1, + token_type: -1, + } + } +} + impl StreamSession { /// return const referance of self /// @@ -71,21 +86,39 @@ impl StreamSession { fn uid(&self) -> i32 { self.uid } + fn pid(&self) -> i32 { self.pid } + fn module_type(&self) -> i32 { self.module_type } + fn session_fd(&self) -> i32 { self.fd } + fn set_token_type(&mut self, style: i32) { self.token_type = style } + + fn set_uid(&mut self, uid: i32) { + self.uid = uid + } + + fn set_pid(&mut self, pid: i32) { + self.pid = pid + } + + fn set_fd(&mut self, fd: i32) { + self.fd = fd + } + fn token_type(&self) -> i32 { self.token_type } + fn session_close(&mut self) { debug!(LOG_LABEL, "Enter fd_:{}.", self.fd); if self.fd >= 0 { @@ -95,21 +128,22 @@ impl StreamSession { self.fd = -1; } } + fn session_send_msg(&self, buf: *const c_char, size: usize) -> bool { if buf.is_null() { - error!(LOG_LABEL, "CHKPF(buf) is null"); + error!(LOG_LABEL, "buf is null"); return false; } if size == 0 || size > MAX_PACKET_BUF_SIZE { - error!(LOG_LABEL, "buf size:{}", size); + error!(LOG_LABEL, "size is either equal to 0 or greater than MAX_PACKET_BUF_SIZE, size: {}", size); return false; } if self.fd < 0 { - error!(LOG_LABEL, "The fd is less than 0"); + error!(LOG_LABEL, "The fd is less than 0, fd: {}", self.fd); return false; } - let mut idx = 0; - let mut retry_count = 0; + let mut idx: usize = 0; + let mut retry_count: i32 = 0; let buf_size = size; let mut rem_size = buf_size; while rem_size > 0 && retry_count < SEND_RETRY_LIMIT { @@ -124,10 +158,7 @@ impl StreamSession { }; if count < 0 { if errno == libc::EAGAIN || errno == libc::EINTR || errno == libc::EWOULDBLOCK { - // safety: call libc library function which is unsafe function - unsafe { - libc::usleep(SEND_RETRY_SLEEP_TIME); - } + sleep(Duration::from_micros(SEND_RETRY_SLEEP_TIME)); error!(LOG_LABEL, "Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:{}", errno); continue; } @@ -137,10 +168,7 @@ impl StreamSession { idx += count as usize; rem_size -= count as usize; if rem_size > 0 { - // safety: call libc library function which is unsafe function - unsafe { - libc::usleep(SEND_RETRY_SLEEP_TIME); - } + sleep(Duration::from_micros(SEND_RETRY_SLEEP_TIME)); } } if retry_count >= SEND_RETRY_LIMIT || rem_size != 0 { @@ -150,6 +178,7 @@ impl StreamSession { } true } + /// session send message pub fn send_msg_pkt(&self, pkt: &NetPacket) -> bool { if pkt.stream_buffer.chk_rwerror() { diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs index 7e676197..0c2d5c77 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs @@ -21,57 +21,109 @@ const LOG_LABEL: HiLogLabel = HiLogLabel { domain: 0xD002220, tag: "stream_session_ffi" }; - -/// get_uid +/// create unique_ptr of stream_session for C++ /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_uid(object: *const StreamSession) -> i32 { - info!(LOG_LABEL, "enter get_uid"); - if let Some(obj) = StreamSession::as_ref(object) { - obj.uid() +pub unsafe extern "C" fn StreamSessionCreate() -> *mut StreamSession { + let stream_session: Box:: = Box::default(); + Box::into_raw(stream_session) +} +/// drop unique_ptr of stream_session for C++ +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSessionDelete(raw: *mut StreamSession) { + if !raw.is_null() { + drop(Box::from_raw(raw)); + } +} +/// StreamSessionSetUid +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSessionSetUid(object: *mut StreamSession, uid: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSessionSetUid"); + if let Some(obj) = StreamSession::as_mut(object) { + obj.set_uid(uid); + SessionStatusCode::Ok.into() } else { - SessionStatusCode::UidFail.into() + SessionStatusCode::Fail.into() + } +} +/// StreamSessionSetFd +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSessionSetFd(object: *mut StreamSession, fd: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSessionSetFd"); + if let Some(obj) = StreamSession::as_mut(object) { + obj.set_fd(fd); + SessionStatusCode::Ok.into() + } else { + SessionStatusCode::Fail.into() } } -/// get_pid +/// StreamSessionSetPid /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_pid(object: *const StreamSession) -> i32 { - info!(LOG_LABEL, "enter get_pid"); +pub unsafe extern "C" fn StreamSessionSetPid(object: *mut StreamSession, pid: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSessionSetPid"); + if let Some(obj) = StreamSession::as_mut(object) { + obj.set_pid(pid); + SessionStatusCode::Ok.into() + } else { + SessionStatusCode::Fail.into() + } +} +/// StreamSessionGetUid +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSessionGetUid(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter StreamSessionGetUid"); if let Some(obj) = StreamSession::as_ref(object) { - obj.pid() + obj.uid() } else { - SessionStatusCode::PidFail.into() + SessionStatusCode::UidFail.into() } } -/// get module type +/// StreamSessionGetPid /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_module_type(object: *const StreamSession) -> i32 { - info!(LOG_LABEL, "enter get_module_type"); +pub unsafe extern "C" fn StreamSessionGetPid(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter StreamSessionGetPid"); if let Some(obj) = StreamSession::as_ref(object) { - obj.module_type() + obj.pid() } else { - SessionStatusCode::ModuleTypeFail.into() + SessionStatusCode::PidFail.into() } } + /// get session fd /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_session_fd(object: *const StreamSession) -> i32 { - info!(LOG_LABEL, "enter get_session_fd"); +pub unsafe extern "C" fn StreamSessionGetFd(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter StreamSessionGetFd"); if let Some(obj) = StreamSession::as_ref(object) { obj.session_fd() } else { @@ -84,8 +136,8 @@ pub unsafe extern "C" fn get_session_fd(object: *const StreamSession) -> i32 { /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn set_token_type(object: *mut StreamSession, style: i32) -> i32 { - info!(LOG_LABEL, "enter set_token_type"); +pub unsafe extern "C" fn StreamSessionSetTokenType(object: *mut StreamSession, style: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSessionSetTokenType"); if let Some(obj) = StreamSession::as_mut(object) { obj.set_token_type(style); SessionStatusCode::Ok.into() @@ -99,22 +151,36 @@ pub unsafe extern "C" fn set_token_type(object: *mut StreamSession, style: i32) /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn get_token_type(object: *const StreamSession) -> i32 { - info!(LOG_LABEL, "enter get_token_type"); +pub unsafe extern "C" fn StreamSessionGetTokenType(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter StreamSessionGetTokenType"); if let Some(obj) = StreamSession::as_ref(object) { obj.token_type() } else { SessionStatusCode::TokenTypeFail.into() } } +/// get module_type +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSessionGetModuleType(object: *const StreamSession) -> i32 { + info!(LOG_LABEL, "enter StreamSessionGetModuleType"); + if let Some(obj) = StreamSession::as_ref(object) { + obj.module_type() + } else { + SessionStatusCode::Fail.into() + } +} /// get session close /// /// # Safety /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn session_close(object: *mut StreamSession) -> i32 { - info!(LOG_LABEL, "enter session_close"); +pub unsafe extern "C" fn StreamSessionClose(object: *mut StreamSession) -> i32 { + info!(LOG_LABEL, "enter StreamSessionClose"); if let Some(obj) = StreamSession::as_mut(object) { obj.session_close(); SessionStatusCode::Ok.into() @@ -129,8 +195,8 @@ pub unsafe extern "C" fn session_close(object: *mut StreamSession) -> i32 { /// /// object must be valid #[no_mangle] -pub unsafe extern "C" fn session_send_msg(object: *const StreamSession, buf: *const c_char, size: usize) -> bool { - info!(LOG_LABEL, "enter session_send_msg"); +pub unsafe extern "C" fn StreamSessionSendMsg(object: *const StreamSession, buf: *const c_char, size: usize) -> bool { + info!(LOG_LABEL, "enter StreamSessionSendMsg"); if let Some(obj) = StreamSession::as_ref(object) { obj.session_send_msg(buf, size) } else { diff --git a/rust/utils/socket_ipc_rust_ffi/test/main.rs b/rust/utils/socket_ipc_rust_ffi/test/main.rs deleted file mode 100644 index a1d8609b..00000000 --- a/rust/utils/socket_ipc_rust_ffi/test/main.rs +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//! socket communication example -#![feature(rustc_private)] - -extern crate sensor_rust_util; -extern crate libc; -use libc::c_int; -use libc::c_char; -use sensor_rust_util::stream_session::StreamSession; -use sensor_rust_util::net_packet::NetPacket; -use sensor_rust_util::net_packet::MessageId; -use sensor_rust_util::stream_socket::StreamSocket; -use sensor_rust_util::stream_buffer::{StreamBuffer, MAX_PACKET_BUF_SIZE}; -use std::mem::size_of; - -unsafe fn read_packets_callback(pkt: *mut NetPacket) { - if let Some(obj) = NetPacket::as_mut(pkt) { - println!("msg_id={}", obj.msg_id as i32); - let mut d: i32 = 0; - let mut e: i32 = 0; - let mut f: i32 = 0; - obj.read(&mut d); - obj.read(&mut e); - obj.read(&mut f); - println!("d={},e={},f={}", d, e, f); - } else { - - } -} - -fn main() { - const MAX_EVENT_SIZE: i32 = 100; - let mut socket_fds: [c_int; 2] = [-1; 2]; - unsafe { - if libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, &mut socket_fds[0]) != 0 { - println!("Call socketpair failed"); - } - } - let server_fd = socket_fds[0]; - let client_fd = socket_fds[1]; - let buffer_size: libc::size_t = 32 * 1024; - - println!("server_fd={}, client_fd={}", server_fd, client_fd); - unsafe { - let pid: libc::pid_t = libc::fork(); - if pid == -1 { - println!("Error: fork failed."); - } else if pid == 0 { - println!("I am the child process, my PID is {}.", libc::getpid()); - libc::close(server_fd); - if libc::setsockopt(client_fd, libc::SOL_SOCKET, libc::SO_SNDBUF, - &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { - println!("setsockopt client_fd failed"); - } - if libc::setsockopt(client_fd, libc::SOL_SOCKET, libc::SO_RCVBUF, - &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { - println!("setsockopt client_fd failed"); - } - let mut events: [libc::epoll_event; MAX_EVENT_SIZE as usize] = [ - libc::epoll_event { - events: 0, - u64: 0, - }; MAX_EVENT_SIZE as usize - ]; - let mut stream_socket: StreamSocket = Default::default(); - let mut ev: libc::epoll_event= libc::epoll_event { - events: 0, - u64: 0, - }; - ev.events = libc::EPOLLIN as u32; - ev.u64 = client_fd as u64; - stream_socket.create_epoll_fd(MAX_EVENT_SIZE); - if StreamSocket::epoll_ctl(client_fd, libc::EPOLL_CTL_ADD, &mut ev, stream_socket.epoll_fd) != 0 { - println!("epoll_ctl fail"); - } - loop { - let _count: i32 = StreamSocket::epoll_wait(&mut events[0], MAX_EVENT_SIZE, -1, stream_socket.epoll_fd); - let mut sz_buf: [c_char; MAX_PACKET_BUF_SIZE] = [0; MAX_PACKET_BUF_SIZE]; - let mut buf: StreamBuffer = Default::default(); - let size = libc::recv(client_fd, &mut sz_buf[0] as *mut c_char as *mut libc::c_void, - MAX_PACKET_BUF_SIZE, libc::MSG_DONTWAIT | libc::MSG_NOSIGNAL); - if !buf.circle_write(&sz_buf[0], size as usize) { - println!("Write data failed. size:{}", size); - } - buf.read_packets(read_packets_callback); - } - } else { - println!("I am the parent process, my PID is {} and my child's PID is {}", libc::getpid(), pid); - libc::close(client_fd); - if libc::setsockopt(server_fd, libc::SOL_SOCKET, libc::SO_SNDBUF, - &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { - println!("setsockopt server_fd failed"); - } - if libc::setsockopt(server_fd, libc::SOL_SOCKET, libc::SO_RCVBUF, - &buffer_size as *const libc::size_t as *const libc::c_void, size_of::() as u32) != 0 { - println!("setsockopt serverFd failed"); - } - let session: StreamSession = StreamSession { - module_type: 0, - fd: server_fd, - uid : 0, - pid, - token_type: 0, - }; - loop { - let mut pkt: NetPacket = NetPacket { - msg_id: MessageId::DragNotifyResult, - ..Default::default() - }; - let a: i32 = 777; - let b: i32 = 888; - let c: i32 = 999; - pkt.write(a); - pkt.write(b); - pkt.write(c); - session.send_msg_pkt(&pkt); - libc::usleep(1000000); - } - } - } -} \ No newline at end of file diff --git a/services/sensor/BUILD.gn b/services/sensor/BUILD.gn index 1dcd7cd4..bc87046e 100644 --- a/services/sensor/BUILD.gn +++ b/services/sensor/BUILD.gn @@ -52,7 +52,7 @@ ohos_shared_library("libsensor_service") { ] if (rust_socket_ipc) { - deps += [ "$SUBSYSTEM_DIR/sensor/rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] + deps += [ "$SUBSYSTEM_DIR/rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] } external_deps = [ diff --git a/services/sensor/src/sensor_power_policy.cpp b/services/sensor/src/sensor_power_policy.cpp index 2d3e64e5..f724f66c 100644 --- a/services/sensor/src/sensor_power_policy.cpp +++ b/services/sensor/src/sensor_power_policy.cpp @@ -195,7 +195,7 @@ void SensorPowerPolicy::ReportActiveInfo(const ActiveInfo &activeInfo, pkt << activeInfo.GetPid() << activeInfo.GetSensorId() << activeInfo.GetSamplingPeriodNs() << activeInfo.GetMaxReportDelayNs(); #ifdef OHOS_BUILD_ENABLE_RUST - if (chk_rwerror(&pkt.rustStreamBuffer_)) { + if (StreamBufferChkRWError(pkt.streamBufferPtr_.get())) { #else if (pkt.ChkRWError()) { #endif // OHOS_BUILD_ENABLE_RUST diff --git a/utils/ipc/include/rust_binding.h b/utils/ipc/include/rust_binding.h index c3de741d..e17b0707 100644 --- a/utils/ipc/include/rust_binding.h +++ b/utils/ipc/include/rust_binding.h @@ -20,79 +20,54 @@ #include "accesstoken_kit.h" extern "C" { - enum class ErrorStatus : int32_t { - ERROR_STATUS_Ok = 0, - ERROR_STATUS_Read = 1, - ERROR_STATUS_Write = 2, - }; - struct RustStreamSocket { - int32_t fd_ { -1 }; - int32_t epollFd_ { -1 }; - }; - struct RustStreamSession { - int32_t moduleType_ { -1 }; - int32_t fd_ { -1 }; - int32_t uid_ { -1 }; - int32_t pid_ { -1 }; - int32_t tokenType_ { OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_INVALID }; - }; - struct RustStreamClient { - bool isExit { false }; - bool isRunning_ { false }; - bool isConnected_ { false }; - }; - struct RustStreamBuffer { - ErrorStatus rwErrorStatus_ { ErrorStatus::ERROR_STATUS_Ok }; - int32_t rCount_ { 0 }; - int32_t wCount_ { 0 }; - int32_t rPos_ { 0 }; - int32_t wPos_ { 0 }; - char szBuff_[OHOS::Sensors::MAX_STREAM_BUF_SIZE+1] { }; - }; - struct RustNetPacket { - OHOS::Sensors::MessageId msgId_ { OHOS::Sensors::MessageId::INVALID }; - struct RustStreamBuffer rustStreamBuffer; - }; - int32_t get_fd(const RustStreamSocket*); - int32_t get_epoll_fd(const RustStreamSocket*); - int32_t rust_epoll_create(RustStreamSocket*, int32_t); - int32_t rust_epoll_ctl(RustStreamSocket*, int32_t, int32_t, struct epoll_event*, int32_t); - int32_t rust_epoll_wait(RustStreamSocket*, struct epoll_event*, int32_t, int32_t, int32_t); - int32_t rust_epoll_close(RustStreamSocket*); - int32_t rust_close(RustStreamSocket*); - bool send_msg_buf_size(const RustStreamSocket*, const char*, size_t); - void session_close(RustStreamSession*); - bool session_send_msg(const RustStreamSession*, const char*, size_t); - bool get_connected_status(const RustStreamClient&); - void stop(RustStreamClient&, RustStreamSocket&); - void reset(RustStreamBuffer*); - void clean(RustStreamBuffer*); - bool read_streambuffer(RustStreamBuffer*, RustStreamBuffer*); - bool write_streambuffer(RustStreamBuffer*, const RustStreamBuffer*); - const char* read_buf(const RustStreamBuffer*); - bool read_char_usize(RustStreamBuffer*, char *, size_t); - bool write_char_usize(RustStreamBuffer*, const char*, size_t); - const char* data(const RustStreamBuffer*); - size_t size(const RustStreamBuffer*); - int32_t unread_size(RustStreamBuffer*); - int32_t get_available_buf_size(RustStreamBuffer*); - const char* get_error_status_remark(const RustStreamBuffer*); - bool chk_rwerror(const RustStreamBuffer*); - bool check_write(RustStreamBuffer*, size_t); - bool circle_write(RustStreamBuffer*, const char*, size_t); - void copy_data_to_begin(RustStreamBuffer*); - int32_t get_uid(const RustStreamSession*); - int32_t get_pid(const RustStreamSession*); - int32_t get_module_type(const RustStreamSession*); - int32_t get_session_fd(const RustStreamSession*); - void set_token_type(RustStreamSession*, int32_t type); - int32_t get_token_type(const RustStreamSession*); - bool seek_read_pos(RustStreamBuffer*, int32_t); - const char* read_buf(const RustStreamBuffer*); - bool is_empty(const RustStreamBuffer*); - size_t get_size(const RustNetPacket*); - int32_t get_packet_length(const RustNetPacket*); - const char* get_data(const RustNetPacket*); - OHOS::Sensors::MessageId get_msg_id(const RustNetPacket*); + struct RustStreamSocket; + struct RustStreamSession; + struct RustStreamBuffer; + struct RustNetPacket; + RustStreamSocket* StreamSocketCreate(void); + void StreamSocketDelete(RustStreamSocket* raw); + int32_t StreamSocketGetFd(const RustStreamSocket* rustStreamSocket); + int32_t StreamSocketGetEpollFd(const RustStreamSocket* rustStreamSocket); + int32_t StreamSocketEpollCreate(RustStreamSocket* rustStreamSocket, int32_t fd); + int32_t StreamSocketEpollCtl(RustStreamSocket* rustStreamSocket, int32_t fd, int32_t op, struct epoll_event* event, int32_t epollFd); + int32_t StreamSocketEpollWait(RustStreamSocket* rustStreamSocket, struct epoll_event* events, int32_t maxevents, int32_t timeout, int32_t epollFd); + int32_t StreamSocketEpollClose(RustStreamSocket* rustStreamSocket); + int32_t StreamSocketClose(RustStreamSocket* rustStreamSocket); + RustStreamSession* StreamSessionCreate(void); + void StreamSessionDelete(RustStreamSession* raw); + void StreamSessionSetUid(RustStreamSession* rustStreamSession, int32_t uid); + void StreamSessionSetPid(RustStreamSession* rustStreamSession, int32_t pid); + void StreamSessionSetFd(RustStreamSession* rustStreamSession, int32_t fd); + void StreamSessionClose(RustStreamSession* rustStreamSession); + bool StreamSessionSendMsg(const RustStreamSession* rustStreamSession, const char* buf, size_t size); + int32_t StreamSessionGetUid(const RustStreamSession* rustStreamSession); + int32_t StreamSessionGetPid(const RustStreamSession* rustStreamSession); + int32_t StreamSessionGetFd(const RustStreamSession* rustStreamSession); + void StreamSessionSetTokenType(RustStreamSession* rustStreamSession, int32_t type); + int32_t StreamSessionGetTokenType(const RustStreamSession* rustStreamSession); + int32_t StreamSessionGetModuleType(const RustStreamSession* rustStreamSession); + RustStreamBuffer* StreamBufferCreate(void); + void StreamBufferDelete(RustStreamBuffer* raw); + int32_t StreamBufferGetWcount(const RustStreamBuffer* rustStreamBuffer); + int32_t StreamBufferGetRcount(const RustStreamBuffer* rustStreamBuffer); + int32_t StreamBufferGetWpos(const RustStreamBuffer* rustStreamBuffer); + int32_t StreamBufferGetRpos(const RustStreamBuffer* rustStreamBuffer); + const char* StreamBufferGetSzBuff(const RustStreamBuffer* rustStreamBuffer); + int32_t StreamBufferSetRwErrStatus(RustStreamBuffer* rustStreamBuffer, int32_t rwErrStatus); + int32_t StreamBufferSetRpos(RustStreamBuffer* rustStreamBuffer, int32_t rPos); + void StreamBufferReset(RustStreamBuffer* rustStreamBuffer); + void StreamBufferClean(RustStreamBuffer* rustStreamBuffer); + bool StreamBufferRead(RustStreamBuffer* rustStreamBuffer1, RustStreamBuffer* rustStreamBuffer2); + bool StreamBufferWrite(RustStreamBuffer* rustStreamBuffer1, const RustStreamBuffer* rustStreamBuffer2); + const char* StreamBufferReadBuf(const RustStreamBuffer* rustStreamBuffer); + bool StreamBufferReadChar(RustStreamBuffer* rustStreamBuffer, char* buf, size_t size); + bool StreamBufferWriteChar(RustStreamBuffer* rustStreamBuffer, const char* buf, size_t size); + const char* StreamBufferData(const RustStreamBuffer* rustStreamBuffer); + size_t StreamBufferSize(const RustStreamBuffer* rustStreamBuffer); + const char* StreamBufferGetErrorStatusRemark(const RustStreamBuffer* rustStreamBuffer); + bool StreamBufferChkRWError(const RustStreamBuffer* rustStreamBuffer); + bool StreamBufferCheckWrite(RustStreamBuffer* rustStreamBuffer, size_t size); + bool CircleStreamBufferWrite(RustStreamBuffer* rustStreamBuffer, const char* buf, size_t size); + void CircleStreamBufferCopyDataToBegin(RustStreamBuffer* rustStreamBuffer); } #endif // RUST_BINDING_H \ No newline at end of file diff --git a/utils/ipc/include/stream_buffer.h b/utils/ipc/include/stream_buffer.h index 591555e7..a1db7a7d 100644 --- a/utils/ipc/include/stream_buffer.h +++ b/utils/ipc/include/stream_buffer.h @@ -78,7 +78,8 @@ protected: bool Clone(const StreamBuffer &buf); #ifdef OHOS_BUILD_ENABLE_RUST public: - struct RustStreamBuffer rustStreamBuffer_; + std::unique_ptr streamBufferPtr_ + { StreamBufferCreate(), StreamBufferDelete }; #else enum class ErrorStatus { ERROR_STATUS_OK, @@ -100,9 +101,9 @@ bool StreamBuffer::Read(T &data) { if (!Read(reinterpret_cast(&data), sizeof(data))) { #ifdef OHOS_BUILD_ENABLE_RUST - const char* s = get_error_status_remark(&rustStreamBuffer_); + const char* s = StreamBufferGetErrorStatusRemark(streamBufferPtr_.get()); SEN_HILOGE("[%{public}s] size:%{public}zu count:%{public}d", - s, sizeof(data), rustStreamBuffer_.rCount_ + 1); + s, sizeof(data), StreamBufferGetRcount(streamBufferPtr_.get()) + 1); #else SEN_HILOGE("%{public}s, size:%{public}zu, count:%{public}zu", GetErrorStatusRemark().c_str(), sizeof(data), rCount_ + 1); @@ -117,9 +118,9 @@ bool StreamBuffer::Write(const T &data) { if (!Write(reinterpret_cast(&data), sizeof(data))) { #ifdef OHOS_BUILD_ENABLE_RUST - const char* s = get_error_status_remark(&rustStreamBuffer_); + const char* s = StreamBufferGetErrorStatusRemark(streamBufferPtr_.get()); SEN_HILOGE("[%{public}s] size:%{public}zu,count:%{public}d", - s, sizeof(data), rustStreamBuffer_.wCount_ + 1); + s, sizeof(data), StreamBufferGetWcount(streamBufferPtr_.get()) + 1); #else SEN_HILOGE("%{public}s, size:%{public}zu, count:%{public}zu", GetErrorStatusRemark().c_str(), sizeof(data), wCount_ + 1); diff --git a/utils/ipc/include/stream_session.h b/utils/ipc/include/stream_session.h index 88dee8c4..e0f25ae0 100644 --- a/utils/ipc/include/stream_session.h +++ b/utils/ipc/include/stream_session.h @@ -66,7 +66,8 @@ protected: std::string descript_; const std::string programName_; #ifdef OHOS_BUILD_ENABLE_RUST - struct RustStreamSession rustStreamSession_; + std::unique_ptr streamSessionPtr_ + { StreamSessionCreate(), StreamSessionDelete }; #else int32_t fd_ { -1 }; const int32_t uid_ { -1 }; diff --git a/utils/ipc/include/stream_socket.h b/utils/ipc/include/stream_socket.h index da3f32f4..f112f52a 100644 --- a/utils/ipc/include/stream_socket.h +++ b/utils/ipc/include/stream_socket.h @@ -31,7 +31,7 @@ #include "circle_stream_buffer.h" #include "net_packet.h" -#ifdef OHOS_BUILD_ENABLE_RUST +#ifdef OHOS_BUILD_ENABLE_RUST #include "rust_binding.h" #endif // OHOS_BUILD_ENABLE_RUST @@ -39,7 +39,7 @@ namespace OHOS { namespace Sensors { class StreamSocket { public: - using PacketCallBackFun = std::function; + using PacketCallBackFun = std::function; StreamSocket(); virtual ~StreamSocket(); int32_t EpollCreate(int32_t size); @@ -51,18 +51,17 @@ public: int32_t GetEpollFd() const; #ifndef OHOS_BUILD_ENABLE_RUST void OnReadPackets(CircleStreamBuffer &buf, PacketCallBackFun callbackFun); -#endif // OHOS_BUILD_ENABLE_RUST +#endif // OHOS_BUILD_ENABLE_RUST DISALLOW_COPY_AND_MOVE(StreamSocket); - protected: #ifdef OHOS_BUILD_ENABLE_RUST - struct RustStreamSocket rustStreamSocket_; + std::unique_ptr streamSocketPtr_ + { StreamSocketCreate(), StreamSocketDelete }; #else - int32_t fd_ { -1 }; - int32_t epollFd_ { -1 }; + int32_t fd_{-1}; + int32_t epollFd_{-1}; #endif // OHOS_BUILD_ENABLE_RUST - }; } // namespace Sensors } // namespace OHOS -#endif // STREAM_SOCKET_H \ No newline at end of file +#endif // STREAM_SOCKET_H \ No newline at end of file diff --git a/utils/ipc/src/circle_stream_buffer.cpp b/utils/ipc/src/circle_stream_buffer.cpp index e526b5b1..ccdafc97 100644 --- a/utils/ipc/src/circle_stream_buffer.cpp +++ b/utils/ipc/src/circle_stream_buffer.cpp @@ -22,7 +22,7 @@ namespace Sensors { bool CircleStreamBuffer::CheckWrite(size_t size) { #ifdef OHOS_BUILD_ENABLE_RUST - return check_write(&rustStreamBuffer_, size); + return StreamBufferCheckWrite(streamBufferPtr_.get(), size); #else size_t availSize = GetAvailableBufSize(); if (size > availSize && rPos_ > 0) { @@ -36,7 +36,7 @@ bool CircleStreamBuffer::CheckWrite(size_t size) bool CircleStreamBuffer::Write(const char *buf, size_t size) { #ifdef OHOS_BUILD_ENABLE_RUST - return circle_write(&rustStreamBuffer_, buf, size); + return CircleStreamBufferWrite(streamBufferPtr_.get(), buf, size); #else if (!CheckWrite(size)) { SEN_HILOGE("Buffer is overflow, availableSize:%{public}zu, size:%{public}zu," @@ -51,7 +51,7 @@ bool CircleStreamBuffer::Write(const char *buf, size_t size) void CircleStreamBuffer::CopyDataToBegin() { #ifdef OHOS_BUILD_ENABLE_RUST - copy_data_to_begin(&rustStreamBuffer_); + CircleStreamBufferCopyDataToBegin(streamBufferPtr_.get()); #else size_t unreadSize = UnreadSize(); if (unreadSize > 0 && rPos_ > 0) { diff --git a/utils/ipc/src/net_packet.cpp b/utils/ipc/src/net_packet.cpp index 11050645..a747b579 100644 --- a/utils/ipc/src/net_packet.cpp +++ b/utils/ipc/src/net_packet.cpp @@ -30,10 +30,10 @@ NetPacket::NetPacket(const NetPacket &pkt) : NetPacket(pkt.GetMsgId()) void NetPacket::MakeData(StreamBuffer &buf) const { #ifdef OHOS_BUILD_ENABLE_RUST - PACKHEAD head = {msgId_, rustStreamBuffer_.wPos_}; + PACKHEAD head = {msgId_, StreamBufferGetWpos(streamBufferPtr_.get())}; buf << head; - if (rustStreamBuffer_.wPos_ > 0) { - if (!buf.Write(&rustStreamBuffer_.szBuff_[0], rustStreamBuffer_.wPos_)) { + if (StreamBufferGetWpos(streamBufferPtr_.get()) > 0) { + if (!buf.Write(StreamBufferGetSzBuff(streamBufferPtr_.get()), StreamBufferGetWpos(streamBufferPtr_.get()))) { SEN_HILOGE("Write data to stream failed"); return; } @@ -53,7 +53,7 @@ void NetPacket::MakeData(StreamBuffer &buf) const size_t NetPacket::GetSize() const { #ifdef OHOS_BUILD_ENABLE_RUST - return size(&rustStreamBuffer_); + return StreamBufferSize(streamBufferPtr_.get()); #else return Size(); #endif // OHOS_BUILD_ENABLE_RUST @@ -62,7 +62,7 @@ size_t NetPacket::GetSize() const size_t NetPacket::GetPacketLength() const { #ifdef OHOS_BUILD_ENABLE_RUST - return (static_cast(sizeof(PackHead)) + rustStreamBuffer_.wPos_); + return (static_cast(sizeof(PackHead)) + StreamBufferGetWpos(streamBufferPtr_.get())); #else return sizeof(PackHead) + wPos_; #endif // OHOS_BUILD_ENABLE_RUST @@ -71,7 +71,7 @@ size_t NetPacket::GetPacketLength() const const char* NetPacket::GetData() const { #ifdef OHOS_BUILD_ENABLE_RUST - return data(&rustStreamBuffer_); + return StreamBufferData(streamBufferPtr_.get()); #else return Data(); #endif // OHOS_BUILD_ENABLE_RUST diff --git a/utils/ipc/src/stream_buffer.cpp b/utils/ipc/src/stream_buffer.cpp index 3ac83c66..f1990556 100644 --- a/utils/ipc/src/stream_buffer.cpp +++ b/utils/ipc/src/stream_buffer.cpp @@ -31,7 +31,7 @@ StreamBuffer &StreamBuffer::operator=(const StreamBuffer &other) void StreamBuffer::Reset() { #ifdef OHOS_BUILD_ENABLE_RUST - reset(&rustStreamBuffer_); + StreamBufferReset(streamBufferPtr_.get()); #else rPos_ = 0; wPos_ = 0; @@ -44,7 +44,7 @@ void StreamBuffer::Reset() void StreamBuffer::Clean() { #ifdef OHOS_BUILD_ENABLE_RUST - clean(&rustStreamBuffer_); + StreamBufferClean(streamBufferPtr_.get()); #else Reset(); errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_)); @@ -58,13 +58,15 @@ void StreamBuffer::Clean() bool StreamBuffer::Read(std::string &buf) { #ifdef OHOS_BUILD_ENABLE_RUST - if (rustStreamBuffer_.rPos_ == rustStreamBuffer_.wPos_) { + const int32_t ERROR_STATUS_READ = 1; + if (StreamBufferGetRpos(streamBufferPtr_.get()) == StreamBufferGetWpos(streamBufferPtr_.get())) { SEN_HILOGE("Not enough memory to read, errCode:%{public}d", STREAM_BUF_READ_FAIL); - rustStreamBuffer_.rwErrorStatus_ = ErrorStatus::ERROR_STATUS_Read; + StreamBufferSetRwErrStatus(streamBufferPtr_.get(), ERROR_STATUS_READ); return false; } buf = ReadBuf(); - rustStreamBuffer_.rPos_ += static_cast(buf.length()) + 1; + StreamBufferSetRpos(streamBufferPtr_.get(), + StreamBufferGetRpos(streamBufferPtr_.get()) + static_cast(buf.length()) + 1); return (buf.length() > 0); #else if (rPos_ == wPos_) { @@ -86,7 +88,7 @@ bool StreamBuffer::Write(const std::string &buf) bool StreamBuffer::Read(StreamBuffer &buf) { #ifdef OHOS_BUILD_ENABLE_RUST - return read_streambuffer(&rustStreamBuffer_, &buf.rustStreamBuffer_); + return StreamBufferRead(streamBufferPtr_.get(), buf.streamBufferPtr_.get()); #else return buf.Write(Data(), Size()); #endif // OHOS_BUILD_ENABLE_RUST @@ -95,7 +97,7 @@ bool StreamBuffer::Read(StreamBuffer &buf) bool StreamBuffer::Write(const StreamBuffer &buf) { #ifdef OHOS_BUILD_ENABLE_RUST - return write_streambuffer(&rustStreamBuffer_, &buf.rustStreamBuffer_); + return StreamBufferWrite(streamBufferPtr_.get(), buf.streamBufferPtr_.get()); #else return Write(buf.Data(), buf.Size()); #endif // OHOS_BUILD_ENABLE_RUST @@ -104,7 +106,7 @@ bool StreamBuffer::Write(const StreamBuffer &buf) bool StreamBuffer::Read(char *buf, size_t size) { #ifdef OHOS_BUILD_ENABLE_RUST - return read_char_usize(&rustStreamBuffer_, buf, size); + return StreamBufferReadChar(streamBufferPtr_.get(), buf, size); #else if (ChkRWError()) { return false; @@ -140,7 +142,7 @@ bool StreamBuffer::Read(char *buf, size_t size) bool StreamBuffer::Write(const char *buf, size_t size) { #ifdef OHOS_BUILD_ENABLE_RUST - return write_char_usize(&rustStreamBuffer_, buf, size); + return StreamBufferWriteChar(streamBufferPtr_.get(), buf, size); #else if (ChkRWError()) { return false; @@ -176,7 +178,7 @@ bool StreamBuffer::Write(const char *buf, size_t size) const char *StreamBuffer::ReadBuf() const { #ifdef OHOS_BUILD_ENABLE_RUST - return read_buf(&rustStreamBuffer_); + return StreamBufferReadBuf(streamBufferPtr_.get()); #else return &szBuff_[rPos_]; #endif // OHOS_BUILD_ENABLE_RUST @@ -186,7 +188,7 @@ bool StreamBuffer::Clone(const StreamBuffer &buf) { Clean(); #ifdef OHOS_BUILD_ENABLE_RUST - return Write(data(&buf.rustStreamBuffer_), size(&buf.rustStreamBuffer_)); + return Write(StreamBufferData(buf.streamBufferPtr_.get()), StreamBufferSize(buf.streamBufferPtr_.get())); #else return Write(buf.Data(), buf.Size()); #endif // OHOS_BUILD_ENABLE_RUST @@ -215,7 +217,11 @@ bool StreamBuffer::ChkRWError() const size_t StreamBuffer::Size() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return StreamBufferSize(&rustStreamBuffer_); +#else return wPos_; +#endif // OHOS_BUILD_ENABLE_RUST } size_t StreamBuffer::UnreadSize() const @@ -244,7 +250,11 @@ const std::string &StreamBuffer::GetErrorStatusRemark() const const char *StreamBuffer::Data() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return StreamBufferData(&rustStreamBuffer_); +#else return &szBuff_[0]; +#endif // OHOS_BUILD_ENABLE_RUST } const char *StreamBuffer::WriteBuf() const diff --git a/utils/ipc/src/stream_session.cpp b/utils/ipc/src/stream_session.cpp index 92618dda..e889e594 100644 --- a/utils/ipc/src/stream_session.cpp +++ b/utils/ipc/src/stream_session.cpp @@ -37,9 +37,9 @@ StreamSession::StreamSession(const std::string &programName, const int32_t fd, c : programName_(programName) #ifdef OHOS_BUILD_ENABLE_RUST { - rustStreamSession_.fd_ = fd; - rustStreamSession_.uid_ = uid; - rustStreamSession_.pid_ = pid; + StreamSessionSetFd(streamSessionPtr_.get(), fd); + StreamSessionSetUid(streamSessionPtr_.get(), uid); + StreamSessionSetPid(streamSessionPtr_.get(), pid); UpdateDescript(); } #else @@ -56,7 +56,7 @@ StreamSession::StreamSession(const std::string &programName, const int32_t fd, c bool StreamSession::SendMsg(const char *buf, size_t size) const { #ifdef OHOS_BUILD_ENABLE_RUST - return session_send_msg(&rustStreamSession_, buf, size); + return StreamSessionSendMsg(streamSessionPtr_.get(), buf, size); #else CHKPF(buf); if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) { @@ -75,7 +75,11 @@ bool StreamSession::SendMsg(const char *buf, size_t size) const auto count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL); if (count < 0) { if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { +#ifdef OHOS_BUILD_ENABLE_RUST + sleep(Duration::from_micros(SEND_RETRY_SLEEP_TIME)); +#else usleep(SEND_RETRY_SLEEP_TIME); +#endif SEN_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d", errno); continue; } @@ -85,7 +89,11 @@ bool StreamSession::SendMsg(const char *buf, size_t size) const idx += static_cast(count); remSize -= static_cast(count); if (remSize > 0) { +#ifdef OHOS_BUILD_ENABLE_RUST + sleep(Duration::from_micros(SEND_RETRY_SLEEP_TIME)); +#else usleep(SEND_RETRY_SLEEP_TIME); +#endif } } if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) { @@ -100,7 +108,7 @@ bool StreamSession::SendMsg(const char *buf, size_t size) const void StreamSession::Close() { #ifdef OHOS_BUILD_ENABLE_RUST - session_close(&rustStreamSession_); + StreamSessionClose(streamSessionPtr_.get()); UpdateDescript(); #else if (fd_ >= 0) { @@ -115,13 +123,13 @@ void StreamSession::UpdateDescript() { #ifdef OHOS_BUILD_ENABLE_RUST std::ostringstream oss; - oss << "fd = " << rustStreamSession_.fd_ + oss << "fd = " << StreamSessionGetFd(streamSessionPtr_.get()) << ", programName = " << programName_ - << ", moduleType = " << rustStreamSession_.moduleType_ - << ((rustStreamSession_.fd_ < 0) ? ", closed" : ", opened") - << ", uid = " << rustStreamSession_.uid_ - << ", pid = " << rustStreamSession_.pid_ - << ", tokenType = " << rustStreamSession_.tokenType_ + << ", moduleType = " << StreamSessionGetModuleType(streamSessionPtr_.get()) + << ((StreamSessionGetFd(streamSessionPtr_.get()) < 0) ? ", closed" : ", opened") + << ", uid = " << StreamSessionGetUid(streamSessionPtr_.get()) + << ", pid = " << StreamSessionGetPid(streamSessionPtr_.get()) + << ", tokenType = " << StreamSessionGetTokenType(streamSessionPtr_.get()) << std::endl; descript_ = oss.str().c_str(); #else @@ -140,13 +148,13 @@ void StreamSession::UpdateDescript() bool StreamSession::SendMsg(const NetPacket &pkt) const { #ifdef OHOS_BUILD_ENABLE_RUST - if (chk_rwerror(&pkt.rustStreamBuffer_)) { + if (StreamBufferChkRWError(pkt.streamBufferPtr_.get())) { SEN_HILOGE("Read and write status is error"); return false; } StreamBuffer buf; pkt.MakeData(buf); - return SendMsg(data(&buf.rustStreamBuffer_), size(&buf.rustStreamBuffer_)); + return SendMsg(StreamBufferData(buf.streamBufferPtr_.get()), StreamBufferSize(buf.streamBufferPtr_.get())); #else if (pkt.ChkRWError()) { SEN_HILOGE("Read and write status failed"); @@ -161,7 +169,7 @@ bool StreamSession::SendMsg(const NetPacket &pkt) const int32_t StreamSession::GetUid() const { #ifdef OHOS_BUILD_ENABLE_RUST - return get_uid(&rustStreamSession_); + return StreamSessionGetUid(streamSessionPtr_.get()); #else return uid_; #endif // OHOS_BUILD_ENABLE_RUST @@ -170,7 +178,7 @@ int32_t StreamSession::GetUid() const int32_t StreamSession::GetPid() const { #ifdef OHOS_BUILD_ENABLE_RUST - return get_pid(&rustStreamSession_); + return StreamSessionGetPid(streamSessionPtr_.get()); #else return pid_; #endif // OHOS_BUILD_ENABLE_RUST @@ -184,7 +192,7 @@ SessionPtr StreamSession::GetSharedPtr() int32_t StreamSession::GetFd() const { #ifdef OHOS_BUILD_ENABLE_RUST - return get_session_fd(&rustStreamSession_); + return StreamSessionGetFd(streamSessionPtr_.get()); #else return fd_; #endif // OHOS_BUILD_ENABLE_RUST @@ -203,7 +211,7 @@ const std::string StreamSession::GetProgramName() const void StreamSession::SetTokenType(int32_t type) { #ifdef OHOS_BUILD_ENABLE_RUST - set_token_type(&rustStreamSession_, type); + StreamSessionSetTokenType(streamSessionPtr_.get(), type); #else tokenType_ = type; #endif // OHOS_BUILD_ENABLE_RUST @@ -212,7 +220,7 @@ void StreamSession::SetTokenType(int32_t type) int32_t StreamSession::GetTokenType() const { #ifdef OHOS_BUILD_ENABLE_RUST - return get_token_type(&rustStreamSession_); + return StreamSessionGetTokenType(streamSessionPtr_.get()); #else return tokenType_; #endif // OHOS_BUILD_ENABLE_RUST diff --git a/utils/ipc/src/stream_socket.cpp b/utils/ipc/src/stream_socket.cpp index 921ddfc9..768b4152 100644 --- a/utils/ipc/src/stream_socket.cpp +++ b/utils/ipc/src/stream_socket.cpp @@ -32,8 +32,8 @@ StreamSocket::StreamSocket() {} StreamSocket::~StreamSocket() { #ifdef OHOS_BUILD_ENABLE_RUST - rust_close(&rustStreamSocket_); - rust_epoll_close(&rustStreamSocket_); + StreamSocketClose(streamSocketPtr_.get()); + StreamSocketEpollClose(streamSocketPtr_.get()); #else Close(); EpollClose(); @@ -43,7 +43,7 @@ StreamSocket::~StreamSocket() int32_t StreamSocket::EpollCreate(int32_t size) { #ifdef OHOS_BUILD_ENABLE_RUST - return rust_epoll_create(&rustStreamSocket_, size); + return StreamSocketEpollCreate(streamSocketPtr_.get(), size); #else epollFd_ = epoll_create(size); if (epollFd_ < 0) { @@ -59,7 +59,7 @@ int32_t StreamSocket::EpollCreate(int32_t size) int32_t StreamSocket::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event, int32_t epollFd) { #ifdef OHOS_BUILD_ENABLE_RUST - return rust_epoll_ctl(&rustStreamSocket_, fd, op, &event, epollFd); + return StreamSocketEpollCtl(streamSocketPtr_.get(), fd, op, &event, epollFd); #else if (fd < 0) { SEN_HILOGE("Invalid fd"); @@ -89,7 +89,7 @@ int32_t StreamSocket::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event int32_t StreamSocket::EpollWait(struct epoll_event &events, int32_t maxevents, int32_t timeout, int32_t epollFd) { #ifdef OHOS_BUILD_ENABLE_RUST - return rust_epoll_wait(&rustStreamSocket_, &events, maxevents, timeout, epollFd); + return StreamSocketEpollWait(streamSocketPtr_.get(), &events, maxevents, timeout, epollFd); #else if (epollFd < 0) { epollFd = epollFd_; @@ -109,7 +109,7 @@ int32_t StreamSocket::EpollWait(struct epoll_event &events, int32_t maxevents, i void StreamSocket::EpollClose() { #ifdef OHOS_BUILD_ENABLE_RUST - rust_epoll_close(&rustStreamSocket_); + StreamSocketEpollClose(streamSocketPtr_.get()); #else if (epollFd_ >= 0) { close(epollFd_); @@ -121,7 +121,7 @@ void StreamSocket::EpollClose() void StreamSocket::Close() { #ifdef OHOS_BUILD_ENABLE_RUST - rust_close(&rustStreamSocket_); + StreamSocketClose(streamSocketPtr_.get()); #else if (fd_ >= 0) { auto rf = close(fd_); @@ -136,7 +136,7 @@ void StreamSocket::Close() int32_t StreamSocket::GetFd() const { #ifdef OHOS_BUILD_ENABLE_RUST - return get_fd(&rustStreamSocket_); + return StreamSocketGetFd(streamSocketPtr_.get()); #else return fd_; #endif // OHOS_BUILD_ENABLE_RUST @@ -144,7 +144,7 @@ int32_t StreamSocket::GetFd() const int32_t StreamSocket::GetEpollFd() const { #ifdef OHOS_BUILD_ENABLE_RUST - return get_epoll_fd(&rustStreamSocket_); + return StreamSocketGetEpollFd(streamSocketPtr_.get()); #else return epollFd_; #endif // OHOS_BUILD_ENABLE_RUST -- Gitee From d2ca8bb93a20587f1ee7b400e4080a52dbbe29b8 Mon Sep 17 00:00:00 2001 From: baiwei Date: Tue, 6 Jun 2023 01:27:55 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A3=80=E8=A7=86=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: baiwei Change-Id: Idfef8b144ff91c91172b142a936e6722e0da341d --- frameworks/native/sensor/BUILD.gn | 6 + .../sensor/include/sensor_service_client.h | 2 +- .../sensor/src/sensor_service_client.cpp | 36 +++- rust/utils/socket_ipc_rust_ffi/src/binding.rs | 4 +- .../socket_ipc_rust_ffi/src/epoll_manager.rs | 67 +------- .../src/epoll_manager/ffi.rs | 28 +++- rust/utils/socket_ipc_rust_ffi/src/error.rs | 25 ++- rust/utils/socket_ipc_rust_ffi/src/lib.rs | 2 +- .../socket_ipc_rust_ffi/src/net_packet.rs | 14 +- .../socket_ipc_rust_ffi/src/stream_buffer.rs | 157 ++---------------- .../src/stream_buffer/ffi.rs | 41 ++--- .../socket_ipc_rust_ffi/src/stream_session.rs | 6 +- .../src/stream_session/ffi.rs | 10 +- sensor.gni | 2 +- utils/ipc/BUILD.gn | 2 +- utils/ipc/include/rust_binding.h | 9 +- utils/ipc/include/stream_buffer.h | 2 +- utils/ipc/src/stream_buffer.cpp | 15 +- 18 files changed, 155 insertions(+), 273 deletions(-) diff --git a/frameworks/native/sensor/BUILD.gn b/frameworks/native/sensor/BUILD.gn index 1ad00abc..df392a2c 100755 --- a/frameworks/native/sensor/BUILD.gn +++ b/frameworks/native/sensor/BUILD.gn @@ -33,11 +33,17 @@ ohos_shared_library("libsensor_native") { "$SUBSYSTEM_DIR/utils/ipc/include", ] + defines = sensor_default_defines + deps = [ "$SUBSYSTEM_DIR/utils/common:libsensor_utils", "$SUBSYSTEM_DIR/utils/ipc:libsensor_ipc", ] + if (rust_socket_ipc) { + deps += [ "$SUBSYSTEM_DIR/rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] + } + external_deps = [ "c_utils:utils", "eventhandler:libeventhandler", diff --git a/frameworks/native/sensor/include/sensor_service_client.h b/frameworks/native/sensor/include/sensor_service_client.h index 0bcc85c8..e544c640 100755 --- a/frameworks/native/sensor/include/sensor_service_client.h +++ b/frameworks/native/sensor/include/sensor_service_client.h @@ -53,13 +53,13 @@ public: int32_t ResetSensors(); void ReceiveMessage(const char *buf, size_t size); void Disconnect(); + void HandleNetPacke(NetPacket &pkt); private: int32_t InitServiceClient(); void UpdateSensorInfoMap(int32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay); void DeleteSensorInfoItem(int32_t sensorId); int32_t CreateSocketChannel(); - void HandleNetPacke(NetPacket &pkt); std::mutex clientMutex_; sptr serviceDeathObserver_; sptr sensorServer_; diff --git a/frameworks/native/sensor/src/sensor_service_client.cpp b/frameworks/native/sensor/src/sensor_service_client.cpp index 3bf51d50..20e73697 100755 --- a/frameworks/native/sensor/src/sensor_service_client.cpp +++ b/frameworks/native/sensor/src/sensor_service_client.cpp @@ -27,6 +27,7 @@ #include "sensor_service_proxy.h" #include "sensors_errors.h" #include "system_ability_definition.h" +#include "rust_binding.h" namespace OHOS { namespace Sensors { @@ -36,6 +37,18 @@ namespace { constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "SensorServiceClient" }; constexpr int32_t GET_SERVICE_MAX_COUNT = 30; constexpr uint32_t WAIT_MS = 200; +#ifdef OHOS_BUILD_ENABLE_RUST +extern "C" { + void ReadClientPackets(RustStreamBuffer*, OHOS::Sensors::SensorServiceClient*, + void(*)(OHOS::Sensors::SensorServiceClient*, RustNetPacket*)); + void OnPacket(SensorServiceClient* object, RustNetPacket* cPkt) + { + NetPacket pkt(cPkt->msgId); + pkt.streamBufferPtr_.reset(cPkt->streamBuffer); + object->HandleNetPacke(pkt); + } +} +#endif // OHOS_BUILD_ENABLE_RUST } // namespace SensorServiceClient::~SensorServiceClient() @@ -357,7 +370,11 @@ void SensorServiceClient::ReceiveMessage(const char *buf, size_t size) if (!circBuf_.Write(buf, size)) { SEN_HILOGE("Write data failed. size:%{public}zu", size); } +#ifdef OHOS_BUILD_ENABLE_RUST + ReadClientPackets(circBuf_.streamBufferPtr_.get(), this, OnPacket); +#else OnReadPackets(circBuf_, std::bind(&SensorServiceClient::HandleNetPacke, this, std::placeholders::_1)); +#endif // OHOS_BUILD_ENABLE_RUST } void SensorServiceClient::HandleNetPacke(NetPacket &pkt) @@ -370,7 +387,11 @@ void SensorServiceClient::HandleNetPacke(NetPacket &pkt) SensorActiveInfo sensorActiveInfo; pkt >> sensorActiveInfo.pid >> sensorActiveInfo.sensorId >> sensorActiveInfo.samplingPeriodNs >> sensorActiveInfo.maxReportDelayNs; +#ifdef OHOS_BUILD_ENABLE_RUST + if (StreamBufferChkRWError(pkt.streamBufferPtr_.get())) { +#else if (pkt.ChkRWError()) { +#endif // OHOS_BUILD_ENABLE_RUST SEN_HILOGE("Packet read type failed"); return; } @@ -385,13 +406,14 @@ void SensorServiceClient::HandleNetPacke(NetPacket &pkt) void SensorServiceClient::Disconnect() { CALL_LOG_ENTER; - if (fd_ < 0) { + int32_t fd = GetFd(); + if (fd < 0) { return; } CHKPV(dataChannel_); - int32_t ret = dataChannel_->DelFdListener(fd_); + int32_t ret = dataChannel_->DelFdListener(fd); if (ret != ERR_OK) { - SEN_HILOGE("Delete fd listener failed, fd:%{public}d, ret:%{public}d", fd_, ret); + SEN_HILOGE("Delete fd listener failed, fd:%{public}d, ret:%{public}d", fd, ret); } Close(); } @@ -414,12 +436,16 @@ int32_t SensorServiceClient::CreateSocketChannel() SEN_HILOGE("Create socket channel failed, ret:%{public}d", ret); return ret; } +#ifdef OHOS_BUILD_ENABLE_RUST + StreamSocketSetFd(streamSocketPtr_.get(), clientFd); +#else fd_ = clientFd; - if (dataChannel_->AddFdListener(fd_, +#endif // OHOS_BUILD_ENABLE_RUST + if (dataChannel_->AddFdListener(GetFd(), std::bind(&SensorServiceClient::ReceiveMessage, this, std::placeholders::_1, std::placeholders::_2), std::bind(&SensorServiceClient::Disconnect, this)) != ERR_OK) { Close(); - SEN_HILOGE("Add fd listener failed, fd:%{public}d", fd_); + SEN_HILOGE("Add fd listener failed, fd:%{public}d", GetFd()); return ERROR; } StartTrace(HITRACE_TAG_SENSORS, "EnableActiveInfoCB"); diff --git a/rust/utils/socket_ipc_rust_ffi/src/binding.rs b/rust/utils/socket_ipc_rust_ffi/src/binding.rs index a163aa3a..4801fdb3 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/binding.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/binding.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,7 +22,7 @@ pub struct CStreamServer { } /// C Client struct pointer #[repr(C)] -pub struct CClient { +pub struct CSensorServiceClient { _private: [u8; 0], } diff --git a/rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs index d5e762a7..096e27f6 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,15 +16,13 @@ /// provide C interface to C++ for calling pub mod ffi; use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; -use std::ptr; +use std::{ptr, ffi::{CString, c_char}}; use libc::c_int; -use std::ffi::{CString, c_char}; -use std::thread::sleep; -use std::time::Duration; const ONCE_PROCESS_NETPACKET_LIMIT: i32 = 100; const MAX_PACKET_BUF_SIZE: usize = 256; const SEND_RETRY_SLEEP_TIME: u64 = 10000; const SEND_RETRY_LIMIT: i32 = 32; +const RET_ERR: i32 = -1; const LOG_LABEL: HiLogLabel = HiLogLabel { log_type: LogType::LogCore, @@ -96,7 +94,7 @@ impl EpollManager { pub fn epoll_ctl(fd: i32, op: i32, event: *mut libc::epoll_event, epoll_fd: i32) -> i32 { if event.is_null() { error!(LOG_LABEL, "event is nullptr"); - return -1; + return RET_ERR; } if op == libc::EPOLL_CTL_DEL { // safety: call unsafe function @@ -133,6 +131,10 @@ impl EpollManager { self.epoll_fd = -1; } } + /// socket_set_fd + pub fn socket_set_fd(&mut self, fd: i32) { + self.socket_fd = fd + } /// socket close pub fn socket_close(&mut self) { if self.socket_fd >= 0 { @@ -145,59 +147,6 @@ impl EpollManager { self.socket_fd = -1; } } - /// send message - /// - /// # Safety - /// - /// call unsafe function - pub unsafe fn send_msg(&self, buf: *const u8, size: usize) -> bool { - if buf.is_null() { - error!(LOG_LABEL, "CHKPF(buf) is null"); - return false; - } - if size == 0 || size > MAX_PACKET_BUF_SIZE { - error!(LOG_LABEL, "Stream buffer size out of range"); - return false; - } - if self.socket_fd < 0 { - error!(LOG_LABEL, "The fd_ is less than 0"); - return false; - } - let mut idx = 0; - let mut retry_count = 0; - let buf_size = size; - let mut rem_size = buf_size; - while rem_size > 0 && retry_count < SEND_RETRY_LIMIT { - retry_count += 1; - let count; - let errno; - unsafe { - count = libc::send(self.socket_fd as c_int, buf.add(idx) as *const libc::c_void, - rem_size, libc::MSG_DONTWAIT | libc::MSG_NOSIGNAL); - errno = *libc::__errno_location(); - } - if count < 0 { - if errno == libc::EAGAIN || errno == libc::EINTR || errno == libc::EWOULDBLOCK { - error!(LOG_LABEL, "Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:{}", errno); - continue; - } - error!(LOG_LABEL, "Send return failed,error:{}, fd:{}", errno, self.socket_fd); - return false; - } - idx += count as usize; - rem_size -= count as usize; - if rem_size > 0 { - sleep(Duration::from_micros(SEND_RETRY_SLEEP_TIME)); - } - } - if retry_count >= SEND_RETRY_LIMIT || rem_size != 0 { - error!(LOG_LABEL, "Send too many times: {}/{}, size: {}/{}, fd: {}", - retry_count, SEND_RETRY_LIMIT, idx, buf_size, self.socket_fd); - return false; - } - true - } - } diff --git a/rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs index 6374bb5a..24133645 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/epoll_manager/ffi.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,14 +15,14 @@ use super::*; use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; -use crate::error::SocketStatusCode; -use crate::epoll_manager::EpollManager; +use crate::{error::SocketStatusCode, epoll_manager::EpollManager}; use std::mem::drop; const LOG_LABEL: HiLogLabel = HiLogLabel { log_type: LogType::LogCore, domain: 0xD002220, tag: "stream_socket_ffi" }; +const RET_ERR: i32 = -1; /// create unique_ptr of stream_socket for C++ /// @@ -89,7 +89,6 @@ pub unsafe extern "C" fn StreamSocketEpollCreate(object: *mut EpollManager, size } else { SocketStatusCode::EpollCreateFail.into() } - } /// StreamSocketEpollCtl @@ -104,14 +103,14 @@ pub unsafe extern "C" fn StreamSocketEpollCtl(object: *const EpollManager, fd: i if let Some(obj) = EpollManager::as_ref(object) { if fd < 0 { error!(LOG_LABEL, "Invalid fd"); - return -1 + return RET_ERR } let epoll_fd = if epoll_fd < 0 { if obj.is_valid_epoll(){ obj.epoll_fd() } else { - return -1; + return RET_ERR; } } else { epoll_fd @@ -137,7 +136,7 @@ pub unsafe extern "C" fn StreamSocketEpollWait( if obj.is_valid_epoll() { obj.epoll_fd() } else { - return -1; + return RET_ERR; } } else { epoll_fd @@ -178,5 +177,20 @@ pub unsafe extern "C" fn StreamSocketClose(object: *mut EpollManager) -> i32 { SocketStatusCode::SocketCloseFail.into() } } +/// StreamSocketSetFd +/// +/// # Safety +/// +/// object must be valid +#[no_mangle] +pub unsafe extern "C" fn StreamSocketSetFd(object: *mut EpollManager, fd: i32) -> i32 { + info!(LOG_LABEL, "enter StreamSocketSetFd"); + if let Some(obj) = EpollManager::as_mut(object) { + obj.socket_set_fd(fd); + SocketStatusCode::Ok.into() + } else { + SocketStatusCode::SocketSetFdFail.into() + } +} diff --git a/rust/utils/socket_ipc_rust_ffi/src/error.rs b/rust/utils/socket_ipc_rust_ffi/src/error.rs index 192c5bf7..7dbf1171 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/error.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/error.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -23,6 +23,7 @@ pub enum SocketStatusCode { EpollWaitFail = -6, EpollCloseFail = -7, SocketCloseFail = -8, + SocketSetFdFail = -9, } pub enum BufferStatusCode { @@ -40,6 +41,12 @@ pub enum BufferStatusCode { ReadServerPacketsFail = -11, ReadClientPacketsFail = -12, SizeFail = -13, + RcountFail = -14, + WcountFail = -15, + WposFail = -16, + RposFail = -17, + SetRwErrStatusFail = -18, + SetRposFail = -19, } pub enum SessionStatusCode { @@ -52,7 +59,11 @@ pub enum SessionStatusCode { SetTokenTypeFail = -6, TokenTypeFail = -7, CloseFail = -8, + SetUidFail = -9, + SetFdFail = -10, + SetPidFail = -11, } + pub enum NetPacketStatusCode { Ok = 0, Fail = -1, @@ -70,10 +81,12 @@ impl From for i32 { SocketStatusCode::EpollWaitFail => -6, SocketStatusCode::EpollCloseFail => -7, SocketStatusCode::SocketCloseFail => -8, + SocketStatusCode::SocketSetFdFail => -9, _ => -1, } } } + impl From for i32 { fn from(code: BufferStatusCode) -> i32 { match code { @@ -90,6 +103,12 @@ impl From for i32 { BufferStatusCode::ReadServerPacketsFail => -11, BufferStatusCode::ReadClientPacketsFail => -12, BufferStatusCode::SizeFail => -13, + BufferStatusCode::RcountFail => -14, + BufferStatusCode::WcountFail => -15, + BufferStatusCode::WposFail => -16, + BufferStatusCode::RposFail => -17, + BufferStatusCode::SetRwErrStatusFail => -18, + BufferStatusCode::SetRposFail => -19, _ => -1, } } @@ -106,10 +125,14 @@ impl From for i32 { SessionStatusCode::SetTokenTypeFail => -6, SessionStatusCode::TokenTypeFail => -7, SessionStatusCode::CloseFail => -8, + SessionStatusCode::SetUidFail => -9, + SessionStatusCode::SetFdFail => -10, + SessionStatusCode::SetPidFail => -11, _ => -1, } } } + impl From for i32 { fn from(code: NetPacketStatusCode) -> i32 { match code { diff --git a/rust/utils/socket_ipc_rust_ffi/src/lib.rs b/rust/utils/socket_ipc_rust_ffi/src/lib.rs index 890fb825..16634727 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/lib.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/lib.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs b/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs index 7fe03051..7e23a996 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/net_packet.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -89,10 +89,20 @@ pub enum MessageId { pub struct NetPacket { /// NetPacket head pub msg_id: MessageId, - /// NetPacket stream buffer + /// NetPacket stream_buffer pub stream_buffer: StreamBuffer, } +/// struct CNetPacket +#[derive(Copy, Clone)] +#[repr(C)] +pub struct CNetPacket { + /// NetPacket head + pub msg_id: MessageId, + /// NetPacket stream_buffer_ptr + pub stream_buffer_ptr: *const StreamBuffer, +} + impl Default for NetPacket { fn default() -> Self { Self { diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs index 11e47635..f93dfa4b 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -19,26 +19,16 @@ use hilog_rust::{info, error, hilog, debug, HiLogLabel, LogType}; use std::ffi::{CString, c_char}; use crate::binding; use std::mem::size_of; -use crate::binding::CStreamServer; -use crate::binding::CClient; -use crate::net_packet::NetPacket; +use crate::binding::CSensorServiceClient; +use crate::net_packet::{NetPacket, CNetPacket}; use crate::net_packet::PackHead; type ErrorStatus = crate::stream_buffer::ErrStatus; /// function pointer alias -pub type ServerPacketCallBackFun = unsafe extern "C" fn ( - stream_server: *const CStreamServer, - fd: i32, - pkt: *const NetPacket, -); -/// function pointer alias pub type ClientPacketCallBackFun = unsafe extern "C" fn ( - client: *const CClient, - pkt: *const NetPacket, -); -/// function pointer alias -pub type ReadPacketCallBackFun = unsafe fn ( - pkt: *mut NetPacket, + client: *const CSensorServiceClient, + pkt: *const CNetPacket, ); + const ONCE_PROCESS_NETPACKET_LIMIT: i32 = 100; const MAX_STREAM_BUF_SIZE: usize = 256; /// max buffer size of packet @@ -306,78 +296,12 @@ impl StreamBuffer { } self.write_char_usize(buf, size) } - /// callback function - /// - ///# Safety - /// - /// call unsafe function - pub unsafe fn read_server_packets(&mut self, stream_server: *const CStreamServer, - fd: i32, callback_fun: ServerPacketCallBackFun) { - const HEAD_SIZE: usize = size_of::(); - for _i in 0..ONCE_PROCESS_NETPACKET_LIMIT { - let unread_size = self.unread_size(); - if unread_size < HEAD_SIZE { - break; - } - let data_size = unread_size - HEAD_SIZE; - let buf: *const c_char = self.read_buf(); - if buf.is_null() { - error!(LOG_LABEL, "buf is null, skip then break"); - break; - } - let head: *const PackHead = buf as *const PackHead; - if head.is_null() { - error!(LOG_LABEL, "head is null, skip then break"); - break; - } - let size; - let id_msg; - unsafe { - size = (*head).size; - id_msg = (*head).id_msg; - } - if !(0..=MAX_PACKET_BUF_SIZE).contains(&size) { - error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ - The buffer will be reset. size:{}, unreadSize:{}", size, unread_size); - self.reset(); - break; - } - if size > data_size { - break; - } - let mut pkt: NetPacket = NetPacket { - msg_id: id_msg, - ..Default::default() - }; - unsafe { - if size > 0 && - !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE) as *const c_char, size) { - error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ - messageid:{}, size:{}", id_msg as i32, size); - break; - } - } - if !self.seek_read_pos(pkt.get_packet_length()) { - error!(LOG_LABEL, "Set read position error, and this error cannot be recovered, and the buffer \ - will be reset. packetSize:{} unreadSize:{}", pkt.get_packet_length(), unread_size); - self.reset(); - break; - } - unsafe { - callback_fun(stream_server, fd, &mut pkt as *const NetPacket); - } - if self.is_empty() { - self.reset(); - break; - } - } - } /// callback of client /// ///# Safety /// /// call unsafe function - pub unsafe fn read_client_packets(&mut self, client: *const CClient, callback_fun: ClientPacketCallBackFun) { + pub unsafe fn read_client_packets(&mut self, client: *const CSensorServiceClient, callback_fun: ClientPacketCallBackFun) { const HEAD_SIZE: usize = size_of::(); for _i in 0..ONCE_PROCESS_NETPACKET_LIMIT { let unread_size = self.unread_size(); @@ -428,72 +352,13 @@ impl StreamBuffer { self.reset(); break; } - unsafe { - callback_fun(client, &pkt as *const NetPacket); - } - if self.is_empty() { - self.reset(); - break; - } - } - } - /// read packets - /// - ///# Safety - /// - /// call unsafe function - pub unsafe fn read_packets(&mut self, callback_fun: ReadPacketCallBackFun) { - const HEAD_SIZE: usize = size_of::(); - for _i in 0..ONCE_PROCESS_NETPACKET_LIMIT { - let unread_size = self.unread_size(); - if unread_size < HEAD_SIZE { - break; - } - let data_size = unread_size - HEAD_SIZE; - let buf: *const c_char = self.read_buf(); - if buf.is_null() { - error!(LOG_LABEL, "buf is null, skip then break"); - break; - } - let head: *const PackHead = buf as *const PackHead; - if head.is_null() { - error!(LOG_LABEL, "head is null, skip then break"); - break; - } - let size; - let id_msg; - unsafe { - size = (*head).size; - id_msg = (*head).id_msg; - } - if !(0..=MAX_PACKET_BUF_SIZE).contains(&size) { - error!(LOG_LABEL, "Packet header parsing error, and this error cannot be recovered. \ - The buffer will be reset. size:{}, unreadSize:{}", size, unread_size); - self.reset(); - break; - } - if size > data_size { - break; - } - let mut pkt: NetPacket = NetPacket { - msg_id: id_msg, - ..Default::default() + let c_net_packet: CNetPacket = CNetPacket { + msg_id: pkt.msg_id, + stream_buffer_ptr: Box::into_raw(Box::new(pkt.stream_buffer)) }; unsafe { - if size > 0 && - !pkt.stream_buffer.write_char_usize(buf.add(HEAD_SIZE) as *const c_char, size) { - error!(LOG_LABEL, "Error writing data in the NetPacket. It will be retried next time. \ - messageid:{}, size:{}", id_msg as i32, size); - break; - } - } - if !self.seek_read_pos(pkt.get_packet_length()) { - error!(LOG_LABEL, "Set read position error, and this error cannot be recovered, and the buffer \ - will be reset. packetSize:{} unreadSize:{}", pkt.get_packet_length(), unread_size); - self.reset(); - break; + callback_fun(client, &c_net_packet as *const CNetPacket); } - callback_fun(&mut pkt as *mut NetPacket); if self.is_empty() { self.reset(); break; diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs index e4b38a37..2311d1b2 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_buffer/ffi.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -144,10 +144,9 @@ pub unsafe extern "C" fn StreamBufferRead(object: *const StreamBuffer, buf: *mut #[no_mangle] pub unsafe extern "C" fn StreamBufferChkRWError(object: *const StreamBuffer) -> bool { if let Some(obj) = StreamBuffer::as_ref(object) { - obj.chk_rwerror() - } else { - false + return obj.chk_rwerror(); } + false } /// StreamBufferGetErrorStatusRemark /// @@ -234,31 +233,15 @@ pub unsafe extern "C" fn CircleStreamBufferWrite(object: *mut StreamBuffer, buf: false } } -/// read_server_packets -/// -/// # Safety -/// -/// object is valid -#[no_mangle] -pub unsafe extern "C" fn read_server_packets(object: *mut StreamBuffer, stream_server: *const CStreamServer, - fd: i32, callback_fun: ServerPacketCallBackFun) -> i32 { - info!(LOG_LABEL,"enter read_server_packets"); - if let Some(obj) = StreamBuffer::as_mut(object) { - obj.read_server_packets(stream_server, fd, callback_fun); - BufferStatusCode::Ok.into() - } else { - BufferStatusCode::ReadServerPacketsFail.into() - } -} -/// read_client_packets +/// ReadClientPackets /// /// # Safety /// /// object is valid #[no_mangle] -pub unsafe extern "C" fn read_client_packets(object: *mut StreamBuffer, stream_client: *const CClient, +pub unsafe extern "C" fn ReadClientPackets(object: *mut StreamBuffer, stream_client: *const CSensorServiceClient, callback_fun: ClientPacketCallBackFun) -> i32 { - info!(LOG_LABEL,"enter read_client_packets"); + info!(LOG_LABEL,"enter ReadClientPackets"); if let Some(obj) = StreamBuffer::as_mut(object) { obj.read_client_packets(stream_client, callback_fun); BufferStatusCode::Ok.into() @@ -289,7 +272,7 @@ pub unsafe extern "C" fn StreamBufferGetRcount(object: *const StreamBuffer) -> i if let Some(obj) = StreamBuffer::as_ref(object) { obj.r_count() as i32 } else { - BufferStatusCode::Fail.into() + BufferStatusCode::RcountFail.into() } } /// StreamBufferGetWcount @@ -302,7 +285,7 @@ pub unsafe extern "C" fn StreamBufferGetWcount(object: *const StreamBuffer) -> i if let Some(obj) = StreamBuffer::as_ref(object) { obj.w_count() as i32 } else { - BufferStatusCode::Fail.into() + BufferStatusCode::WcountFail.into() } } /// StreamBufferGetWpos @@ -315,7 +298,7 @@ pub unsafe extern "C" fn StreamBufferGetWpos(object: *const StreamBuffer) -> i32 if let Some(obj) = StreamBuffer::as_ref(object) { obj.w_pos() as i32 } else { - BufferStatusCode::Fail.into() + BufferStatusCode::WposFail.into() } } /// StreamBufferGetRpos @@ -328,7 +311,7 @@ pub unsafe extern "C" fn StreamBufferGetRpos(object: *const StreamBuffer) -> i32 if let Some(obj) = StreamBuffer::as_ref(object) { obj.r_pos() as i32 } else { - BufferStatusCode::Fail.into() + BufferStatusCode::RposFail.into() } } /// StreamBufferGetSzBuff @@ -355,7 +338,7 @@ pub unsafe extern "C" fn StreamBufferSetRwErrStatus(object: *mut StreamBuffer, r obj.set_rw_error_status(rw_error_status); BufferStatusCode::Ok.into() } else { - BufferStatusCode::Fail.into() + BufferStatusCode::SetRwErrStatusFail.into() } } /// StreamBufferSetRpos @@ -369,7 +352,7 @@ pub unsafe extern "C" fn StreamBufferSetRpos(object: *mut StreamBuffer, r_pos: i obj.set_r_pos(r_pos as usize); BufferStatusCode::Ok.into() } else { - BufferStatusCode::Fail.into() + BufferStatusCode::SetRposFail.into() } } diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs index b7cb4e7f..3a14f746 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_session.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,9 +17,7 @@ pub mod ffi; use hilog_rust::{debug, error, hilog, HiLogLabel, LogType}; use libc::{int32_t, int64_t, c_int}; -use std::ffi::{CString, c_char}; -use std::thread::sleep; -use std::time::Duration; +use std::{ffi::{CString, c_char}, thread::sleep, time::Duration}; use crate::net_packet::NetPacket; use crate::stream_buffer::StreamBuffer; const LOG_LABEL: HiLogLabel = HiLogLabel { diff --git a/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs b/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs index 0c2d5c77..496ed19e 100644 --- a/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs +++ b/rust/utils/socket_ipc_rust_ffi/src/stream_session/ffi.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -54,7 +54,7 @@ pub unsafe extern "C" fn StreamSessionSetUid(object: *mut StreamSession, uid: i3 obj.set_uid(uid); SessionStatusCode::Ok.into() } else { - SessionStatusCode::Fail.into() + SessionStatusCode::SetUidFail.into() } } /// StreamSessionSetFd @@ -69,7 +69,7 @@ pub unsafe extern "C" fn StreamSessionSetFd(object: *mut StreamSession, fd: i32) obj.set_fd(fd); SessionStatusCode::Ok.into() } else { - SessionStatusCode::Fail.into() + SessionStatusCode::SetFdFail.into() } } /// StreamSessionSetPid @@ -84,7 +84,7 @@ pub unsafe extern "C" fn StreamSessionSetPid(object: *mut StreamSession, pid: i3 obj.set_pid(pid); SessionStatusCode::Ok.into() } else { - SessionStatusCode::Fail.into() + SessionStatusCode::SetPidFail.into() } } /// StreamSessionGetUid @@ -170,7 +170,7 @@ pub unsafe extern "C" fn StreamSessionGetModuleType(object: *const StreamSession if let Some(obj) = StreamSession::as_ref(object) { obj.module_type() } else { - SessionStatusCode::Fail.into() + SessionStatusCode::ModuleTypeFail.into() } } /// get session close diff --git a/sensor.gni b/sensor.gni index 86cf839a..0a8dccb4 100644 --- a/sensor.gni +++ b/sensor.gni @@ -14,7 +14,7 @@ import("//build/ohos.gni") declare_args() { - rust_socket_ipc = false + rust_socket_ipc = true } SUBSYSTEM_DIR = "//base/sensors/sensor" diff --git a/utils/ipc/BUILD.gn b/utils/ipc/BUILD.gn index 23ae470a..3710dd37 100644 --- a/utils/ipc/BUILD.gn +++ b/utils/ipc/BUILD.gn @@ -32,7 +32,7 @@ ohos_shared_library("libsensor_ipc") { defines = sensor_default_defines if (rust_socket_ipc) { - deps = [ "../../rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] + deps = [ "$SUBSYSTEM_DIR/rust/utils/socket_ipc_rust_ffi:sensor_rust_util_ffi" ] } external_deps = [ diff --git a/utils/ipc/include/rust_binding.h b/utils/ipc/include/rust_binding.h index e17b0707..b66b1586 100644 --- a/utils/ipc/include/rust_binding.h +++ b/utils/ipc/include/rust_binding.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,13 +17,15 @@ #include #include #include "proto.h" -#include "accesstoken_kit.h" extern "C" { struct RustStreamSocket; struct RustStreamSession; struct RustStreamBuffer; - struct RustNetPacket; + struct RustNetPacket { + OHOS::Sensors::MessageId msgId { OHOS::Sensors::MessageId::INVALID }; + struct RustStreamBuffer* streamBuffer; + }; RustStreamSocket* StreamSocketCreate(void); void StreamSocketDelete(RustStreamSocket* raw); int32_t StreamSocketGetFd(const RustStreamSocket* rustStreamSocket); @@ -33,6 +35,7 @@ extern "C" { int32_t StreamSocketEpollWait(RustStreamSocket* rustStreamSocket, struct epoll_event* events, int32_t maxevents, int32_t timeout, int32_t epollFd); int32_t StreamSocketEpollClose(RustStreamSocket* rustStreamSocket); int32_t StreamSocketClose(RustStreamSocket* rustStreamSocket); + int32_t StreamSocketSetFd(RustStreamSocket* rustStreamSocket, int32_t fd); RustStreamSession* StreamSessionCreate(void); void StreamSessionDelete(RustStreamSession* raw); void StreamSessionSetUid(RustStreamSession* rustStreamSession, int32_t uid); diff --git a/utils/ipc/include/stream_buffer.h b/utils/ipc/include/stream_buffer.h index a1db7a7d..619b9964 100644 --- a/utils/ipc/include/stream_buffer.h +++ b/utils/ipc/include/stream_buffer.h @@ -48,9 +48,9 @@ public: bool Write(const StreamBuffer &buf); virtual bool Write(const char *buf, size_t size); #ifndef OHOS_BUILD_ENABLE_RUST + bool ChkRWError() const; bool SeekReadPos(size_t n); bool IsEmpty() const; - bool ChkRWError() const; size_t Size() const; size_t UnreadSize() const; size_t GetAvailableBufSize() const; diff --git a/utils/ipc/src/stream_buffer.cpp b/utils/ipc/src/stream_buffer.cpp index f1990556..bca85485 100644 --- a/utils/ipc/src/stream_buffer.cpp +++ b/utils/ipc/src/stream_buffer.cpp @@ -194,6 +194,12 @@ bool StreamBuffer::Clone(const StreamBuffer &buf) #endif // OHOS_BUILD_ENABLE_RUST } #ifndef OHOS_BUILD_ENABLE_RUST + +bool StreamBuffer::ChkRWError() const +{ + return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK); +} + bool StreamBuffer::SeekReadPos(size_t n) { size_t pos = rPos_ + n; @@ -210,11 +216,6 @@ bool StreamBuffer::IsEmpty() const return (rPos_ == wPos_); } -bool StreamBuffer::ChkRWError() const -{ - return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK); -} - size_t StreamBuffer::Size() const { #ifdef OHOS_BUILD_ENABLE_RUST @@ -236,6 +237,9 @@ size_t StreamBuffer::GetAvailableBufSize() const const std::string &StreamBuffer::GetErrorStatusRemark() const { +#ifdef OHOS_BUILD_ENABLE_RUST + return StreamBufferGetErrorStatusRemark(streamBufferPtr_.get()); +#else static const std::vector> remark { {ErrorStatus::ERROR_STATUS_OK, "OK"}, {ErrorStatus::ERROR_STATUS_READ, "READ_ERROR"}, @@ -246,6 +250,7 @@ const std::string &StreamBuffer::GetErrorStatusRemark() const return (item.first == rwErrorStatus_); }); return (tIter != remark.cend() ? tIter->second : invalidStatus); +#endif // OHOS_BUILD_ENABLE_RUST } const char *StreamBuffer::Data() const -- Gitee