1 /*
2 * Copyright (C) 2024 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 #include "IpcStub.h"
17 #include <IPCKit/ipc_error_code.h>
18 #include <cstring>
19 #include <new>
20
IpcStub()21 IpcStub::IpcStub()
22 {
23 ipcStub_ = OH_IPCRemoteStub_Create("NativeChildIPCStubSample",
24 IpcStub::OnRemoteRequest, IpcStub::OnRemoteObjectDestory, this);
25 }
26
~IpcStub()27 IpcStub::~IpcStub()
28 {
29 OH_IPCRemoteStub_Destroy(ipcStub_);
30 }
31
GetIpcStub()32 OHIPCRemoteStub* IpcStub::GetIpcStub()
33 {
34 return ipcStub_;
35 }
36
OnRemoteObjectDestory(void * userData)37 void IpcStub::OnRemoteObjectDestory(void *userData)
38 {
39 }
40
OnRemoteRequest(uint32_t code,const OHIPCParcel * data,OHIPCParcel * reply,void * userData)41 int IpcStub::OnRemoteRequest(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply, void *userData)
42 {
43 if (userData == nullptr) {
44 return OH_IPC_CHECK_PARAM_ERROR;
45 }
46
47 if (!CheckInterfaceToken(data)) {
48 return OH_IPC_CHECK_PARAM_ERROR;
49 }
50
51 int ret;
52 IpcStub *thiz = reinterpret_cast<IpcStub*>(userData);
53 switch (code) {
54 case IPC_ID_REQUEST_EXIT_PROCESS:
55 ret = thiz->HandleRequestExitChildProcess(data, reply);
56 break;
57
58 case IPC_ID_ADD:
59 ret = thiz->HandleAdd(data, reply);
60 break;
61
62 case IPC_ID_START_NATIVE_CHILD_PROCESS:
63 ret = thiz->HandleStartNativeChildProcess(data, reply);
64 break;
65
66 default:
67 ret = OH_IPC_CODE_OUT_OF_RANGE;
68 break;
69 }
70
71 return ret;
72 }
73
OnIpcMemAlloc(int32_t len)74 void* IpcStub::OnIpcMemAlloc(int32_t len)
75 {
76 // limit ipc memory alloc size to 128 bytes
77 if (len > 128) {
78 return nullptr;
79 }
80
81 return new (std::nothrow) char[len];
82 }
83
ReleaseIpcMem(void * ipcMem)84 void IpcStub::ReleaseIpcMem(void* ipcMem)
85 {
86 delete[] reinterpret_cast<char*>(ipcMem);
87 }
88
CheckInterfaceToken(const OHIPCParcel * data)89 bool IpcStub::CheckInterfaceToken(const OHIPCParcel* data)
90 {
91 char *token;
92 int32_t tokenLen;
93 int ret = OH_IPCParcel_ReadInterfaceToken(data, &token, &tokenLen, IpcStub::OnIpcMemAlloc);
94 if (ret != OH_IPC_SUCCESS) {
95 return false;
96 }
97
98 bool tokenCheckRes = strcmp(token, interfaceToken_) == 0;
99 ReleaseIpcMem(token);
100 return tokenCheckRes;
101 }
102
HandleRequestExitChildProcess(const OHIPCParcel * data,OHIPCParcel * reply)103 int IpcStub::HandleRequestExitChildProcess(const OHIPCParcel *data, OHIPCParcel *reply)
104 {
105 int exitCode = 0;
106 if (OH_IPCParcel_ReadInt32(data, &exitCode) != OH_IPC_SUCCESS) {
107 return OH_IPC_PARCEL_READ_ERROR;
108 }
109 int32_t ret = RequestExitChildProcess(exitCode) ? 1 : 0;
110 return OH_IPCParcel_WriteInt32(reply, ret);
111 }
112
HandleAdd(const OHIPCParcel * data,OHIPCParcel * reply)113 int32_t IpcStub::HandleAdd(const OHIPCParcel *data, OHIPCParcel *reply)
114 {
115 int32_t a = 0;
116 int32_t b = 0;
117 if (OH_IPCParcel_ReadInt32(data, &a) != OH_IPC_SUCCESS ||
118 OH_IPCParcel_ReadInt32(data, &b) != OH_IPC_SUCCESS) {
119 return OH_IPC_PARCEL_READ_ERROR;
120 }
121
122 int32_t result = Add(a, b);
123 if (OH_IPCParcel_WriteInt32(reply, result) != OH_IPC_SUCCESS) {
124 return OH_IPC_PARCEL_WRITE_ERROR;
125 }
126
127 return OH_IPC_SUCCESS;
128 }
129
HandleStartNativeChildProcess(const OHIPCParcel * data,OHIPCParcel * reply)130 int IpcStub::HandleStartNativeChildProcess(const OHIPCParcel *data, OHIPCParcel *reply)
131 {
132 int32_t ret = StartNativeChildProcess();
133 return OH_IPCParcel_WriteInt32(reply, ret);
134 }
135