1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 //! This create implement the IPC proxy and stub for "example.calc.ipc.ICalcService"
17
18 extern crate ipc_rust;
19
20 mod access_token;
21
22 use ipc_rust::{
23 IRemoteBroker, IRemoteObj, RemoteStub, IpcResult,
24 IpcStatusCode, RemoteObj, define_remote_object, FIRST_CALL_TRANSACTION,
25 };
26 use ipc_rust::{
27 MsgParcel, BorrowedMsgParcel,
28 };
29 use std::convert::{TryFrom, TryInto};
30 pub use access_token::init_access_token;
31
32 /// add num1 + num2
add(num1: &i32, num2: &i32) -> i3233 pub fn add(num1: &i32, num2: &i32) -> i32 {
34 num1 + num2
35 }
36
37 /// sub num1 + num2
sub(num1: &i32, num2: &i32) -> i3238 pub fn sub(num1: &i32, num2: &i32) -> i32 {
39 num1 - num2
40 }
41
42 /// mul num1 + num2
mul(num1: &i32, num2: &i32) -> i3243 pub fn mul(num1: &i32, num2: &i32) -> i32 {
44 num1 * num2
45 }
46
47 /// div num1 + num2
div(num1: &i32, num2: &i32) -> i3248 pub fn div(num1: &i32, num2: &i32) -> i32 {
49 match num2 {
50 0 => {
51 println!("Zero cannot be divided");
52 -1
53 },
54 _ => num1 / num2,
55 }
56 }
57
58 /// SA ID for "example.calc.ipc.ICalcService"
59 pub const EXAMPLE_IPC_CALC_SERVICE_ID: i32 = 1118;
60
61 /// Function code of ICalcService
62 pub enum ICalcCode {
63 /// add
64 CodeAdd = FIRST_CALL_TRANSACTION,
65 /// sub
66 CodeSub,
67 /// mul
68 CodeMul,
69 /// div
70 CodeDiv,
71 }
72
73 impl TryFrom<u32> for ICalcCode {
74 type Error = IpcStatusCode;
try_from(code: u32) -> IpcResult<Self>75 fn try_from(code: u32) -> IpcResult<Self> {
76 match code {
77 _ if code == ICalcCode::CodeAdd as u32 => Ok(ICalcCode::CodeAdd),
78 _ if code == ICalcCode::CodeSub as u32 => Ok(ICalcCode::CodeSub),
79 _ if code == ICalcCode::CodeMul as u32 => Ok(ICalcCode::CodeMul),
80 _ if code == ICalcCode::CodeDiv as u32 => Ok(ICalcCode::CodeDiv),
81 _ => Err(IpcStatusCode::Failed),
82 }
83 }
84 }
85
86 /// Function between proxy and stub of ICalcService
87 pub trait ICalc: IRemoteBroker {
88 /// Calc add num1 + num2
add(&self, num1: i32, num2: i32) -> IpcResult<i32>89 fn add(&self, num1: i32, num2: i32) -> IpcResult<i32>;
90 /// Calc sub num1 + num2
sub(&self, num1: i32, num2: i32) -> IpcResult<i32>91 fn sub(&self, num1: i32, num2: i32) -> IpcResult<i32>;
92 /// Calc mul num1 + num2
mul(&self, num1: i32, num2: i32) -> IpcResult<i32>93 fn mul(&self, num1: i32, num2: i32) -> IpcResult<i32>;
94 /// Calc div num1 + num2
div(&self, num1: i32, num2: i32) -> IpcResult<i32>95 fn div(&self, num1: i32, num2: i32) -> IpcResult<i32>;
96 }
97
on_icalc_remote_request(stub: &dyn ICalc, code: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> IpcResult<()>98 fn on_icalc_remote_request(stub: &dyn ICalc, code: u32, data: &BorrowedMsgParcel,
99 reply: &mut BorrowedMsgParcel) -> IpcResult<()> {
100 match code.try_into()? {
101 ICalcCode::CodeAdd => {
102 let num1: i32 = data.read().expect("Failed to read num1 in addition operation");
103 let num2: i32 = data.read().expect("Failed to read num2 in addition operation");
104 let ret = stub.add(num1, num2)?;
105 reply.write(&ret)?;
106 Ok(())
107 }
108 ICalcCode::CodeSub => {
109 let num1: i32 = data.read().expect("Failed to read num1 in subtraction operation");
110 let num2: i32 = data.read().expect("Failed to read num1 in subtraction operation");
111 let ret = stub.sub(num1, num2)?;
112 reply.write(&ret)?;
113 Ok(())
114 }
115 ICalcCode::CodeMul => {
116 let num1: i32 = data.read().expect("Failed to read num1 in multiplication operation");
117 let num2: i32 = data.read().expect("Failed to read num1 in multiplication operation");
118 let ret = stub.mul(num1, num2)?;
119 reply.write(&ret)?;
120 Ok(())
121 }
122 ICalcCode::CodeDiv => {
123 let num1: i32 = data.read().expect("Failed to read num1 in division operation");
124 let num2: i32 = data.read().expect("Failed to read num1 in division operation");
125 let ret = stub.div(num1, num2)?;
126 reply.write(&ret)?;
127 Ok(())
128 }
129 }
130 }
131
132 define_remote_object!(
133 ICalc["example.calc.ipc.ICalcService"] {
134 stub: CalcStub(on_icalc_remote_request),
135 proxy: CalcProxy,
136 }
137 );
138
139 // Make RemoteStub<CalcStub> object can call ICalc function directly.
140 impl ICalc for RemoteStub<CalcStub> {
add(&self, num1: i32, num2: i32) -> IpcResult<i32>141 fn add (&self, num1: i32, num2: i32) -> IpcResult<i32> {
142 self.0.add(num1, num2)
143 }
sub(&self, num1: i32, num2: i32) -> IpcResult<i32>144 fn sub (&self, num1: i32, num2: i32) -> IpcResult<i32> {
145 self.0.sub(num1, num2)
146 }
mul(&self, num1: i32, num2: i32) -> IpcResult<i32>147 fn mul (&self, num1: i32, num2: i32) -> IpcResult<i32> {
148 self.0.mul(num1, num2)
149 }
div(&self, num1: i32, num2: i32) -> IpcResult<i32>150 fn div (&self, num1: i32, num2: i32) -> IpcResult<i32> {
151 self.0.div(num1, num2)
152 }
153 }
154
155 impl ICalc for CalcProxy {
add(&self, num1: i32, num2: i32) -> IpcResult<i32>156 fn add(&self, num1: i32, num2: i32) -> IpcResult<i32> {
157 let mut data = MsgParcel::new().expect("MsgParcel should success");
158 data.write(&num1)?;
159 data.write(&num2)?;
160 let reply = self.remote.send_request(ICalcCode::CodeAdd as u32,
161 &data, false)?;
162 let ret: i32 = reply.read().expect("need reply i32");
163 Ok(ret)
164 }
sub(&self, num1: i32, num2: i32) -> IpcResult<i32>165 fn sub(&self, num1: i32, num2: i32) -> IpcResult<i32> {
166 let mut data = MsgParcel::new().expect("MsgParcel should success");
167 data.write(&num1)?;
168 data.write(&num2)?;
169 let reply = self.remote.send_request(ICalcCode::CodeSub as u32,
170 &data, false)?;
171 let ret: i32 = reply.read().expect("need reply i32");
172 Ok(ret)
173 }
mul(&self, num1: i32, num2: i32) -> IpcResult<i32>174 fn mul(&self, num1: i32, num2: i32) -> IpcResult<i32> {
175 let mut data = MsgParcel::new().expect("MsgParcel should success");
176 data.write(&num1)?;
177 data.write(&num2)?;
178 let reply = self.remote.send_request(ICalcCode::CodeMul as u32,
179 &data, false)?;
180 let ret: i32 = reply.read().expect("need reply i32");
181 Ok(ret)
182 }
div(&self, num1: i32, num2: i32) -> IpcResult<i32>183 fn div(&self, num1: i32, num2: i32) -> IpcResult<i32> {
184 let mut data = MsgParcel::new().expect("MsgParcel should success");
185 data.write(&num1)?;
186 data.write(&num2)?;
187 let reply = self.remote.send_request(ICalcCode::CodeDiv as u32,
188 &data, false)?;
189 let ret: i32 = reply.read().expect("need reply i32");
190 Ok(ret)
191 }
192 }