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 "ipc_cremote_object.h"
17 #include "ipc_inner_object.h"
18 #include "ipc_internal_utils.h"
19 #include "ipc_remote_object_internal.h"
20 #include "log_tags.h"
21 #include "ipc_debug.h"
22 #include "ipc_error_code.h"
23 #include "ipc_types.h"
24 #include "sys_binder.h"
25
26 #include <securec.h>
27
28 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, OHOS::LOG_ID_IPC_CAPI, "IPCRemoteObject" };
29
30 static constexpr uint32_t MIN_SEND_REQUEST_CODE = 0x01;
31 static constexpr uint32_t MAX_SEND_REQUEST_CODE = 0x00ffffff;
32
OH_IPCRemoteStub_Create(const char * descriptor,OH_OnRemoteRequestCallback requestCallback,OH_OnRemoteDestroyCallback destroyCallback,void * userData)33 OHIPCRemoteStub* OH_IPCRemoteStub_Create(const char *descriptor, OH_OnRemoteRequestCallback requestCallback,
34 OH_OnRemoteDestroyCallback destroyCallback, void *userData)
35 {
36 if (descriptor == nullptr || requestCallback == nullptr) {
37 ZLOGE(LOG_LABEL, "check param error!");
38 return nullptr;
39 }
40 int len = strlen(descriptor);
41 if (len == 0 || len > MAX_PARCEL_LEN) {
42 ZLOGE(LOG_LABEL, "descriptor len:%{public}d is invalid!", len);
43 return nullptr;
44 }
45 std::u16string desc = OHOS::Str8ToStr16(std::string(descriptor));
46 if (desc.length() == 0 && len != 0) {
47 ZLOGE(LOG_LABEL, "convert descriptor to u16string failed: %{public}d", len);
48 return nullptr;
49 }
50 OHOS::sptr<OHIPCRemoteServiceStub> serviceStub(new (std::nothrow) OHIPCRemoteServiceStub(desc,
51 requestCallback, destroyCallback, userData));
52 if (serviceStub == nullptr) {
53 ZLOGE(LOG_LABEL, "new OHIPCRemoteServiceStub failed");
54 return nullptr;
55 }
56 OHIPCRemoteStub *stub = new (std::nothrow) OHIPCRemoteStub();
57 if (stub == nullptr) {
58 ZLOGE(LOG_LABEL, "new OHIPCRemoteStub failed");
59 return nullptr;
60 }
61 stub->remote = serviceStub;
62 return stub;
63 }
64
OH_IPCRemoteStub_Destroy(OHIPCRemoteStub * stub)65 void OH_IPCRemoteStub_Destroy(OHIPCRemoteStub *stub)
66 {
67 if (stub != nullptr) {
68 stub->remote = nullptr;
69 delete stub;
70 }
71 }
72
OH_IPCRemoteProxy_Destroy(OHIPCRemoteProxy * proxy)73 void OH_IPCRemoteProxy_Destroy(OHIPCRemoteProxy *proxy)
74 {
75 if (proxy != nullptr) {
76 proxy->remote = nullptr;
77 delete proxy;
78 }
79 }
80
GetMessageFlag(OH_IPC_RequestMode mode)81 static int GetMessageFlag(OH_IPC_RequestMode mode)
82 {
83 return (mode == OH_IPC_REQUEST_MODE_ASYNC) ?
84 OHOS::MessageOption::TF_ASYNC : OHOS::MessageOption::TF_SYNC;
85 }
86
87 static constexpr struct {
88 int innerErrorCode;
89 int error;
90 } ERROR_MAP[] = {
91 {OHOS::IPC_PROXY_DEAD_OBJECT_ERR, OH_IPC_DEAD_REMOTE_OBJECT},
92 {OHOS::IPC_INVOKER_CONNECT_ERR, OH_IPC_INNER_ERROR},
93 {OHOS::IPC_PROXY_INVALID_CODE_ERR, OH_IPC_CODE_OUT_OF_RANGE},
94 {OHOS::IPC_STUB_WRITE_PARCEL_ERR, OH_IPC_PARCEL_WRITE_ERROR},
95 {OH_IPC_INVALID_USER_ERROR_CODE, OH_IPC_INVALID_USER_ERROR_CODE},
96 {BR_DEAD_REPLY, OH_IPC_DEAD_REMOTE_OBJECT},
97 {BR_FAILED_REPLY, OH_IPC_INNER_ERROR},
98 };
99
ConvertSendRequestError(int error)100 static int ConvertSendRequestError(int error)
101 {
102 if (error == OHOS::ERR_NONE) {
103 return OH_IPC_SUCCESS;
104 }
105 if (IsUserDefinedError(error) || IsIpcErrorCode(error)) {
106 return error;
107 }
108
109 static size_t arraySize = sizeof(ERROR_MAP) / sizeof(ERROR_MAP[0]);
110 for (size_t i = 0; i < arraySize; ++i) {
111 if (ERROR_MAP[i].innerErrorCode == error) {
112 return ERROR_MAP[i].error;
113 }
114 }
115
116 return OH_IPC_INNER_ERROR;
117 }
118
IsCodeValid(uint32_t code)119 static bool IsCodeValid(uint32_t code)
120 {
121 return (code >= MIN_SEND_REQUEST_CODE) && (code <= MAX_SEND_REQUEST_CODE);
122 }
123
OH_IPCRemoteProxy_SendRequest(const OHIPCRemoteProxy * proxy,uint32_t code,const OHIPCParcel * data,OHIPCParcel * reply,const OH_IPC_MessageOption * option)124 int OH_IPCRemoteProxy_SendRequest(const OHIPCRemoteProxy *proxy, uint32_t code, const OHIPCParcel *data,
125 OHIPCParcel *reply, const OH_IPC_MessageOption *option)
126 {
127 if (!IsIPCRemoteProxyValid(proxy, __func__)
128 || !IsIPCParcelValid(data, __func__)
129 || (option != nullptr && option->reserved != nullptr)) {
130 return OH_IPC_CHECK_PARAM_ERROR;
131 }
132 if (!IsCodeValid(code)) {
133 ZLOGE(LOG_LABEL, "send request code:%{public}d out of range[%{public}d, %{public}d]",
134 code, MIN_SEND_REQUEST_CODE, MAX_SEND_REQUEST_CODE);
135 return OH_IPC_CODE_OUT_OF_RANGE;
136 }
137
138 OH_IPC_RequestMode mode = (option != nullptr) ? option->mode : OH_IPC_REQUEST_MODE_SYNC;
139 int ret = OH_IPC_SUCCESS;
140 OHOS::MessageOption msgOption(GetMessageFlag(mode));
141 if (IsIPCParcelValid(reply, __func__)) {
142 ret = proxy->remote->SendRequest(code, *data->msgParcel, *reply->msgParcel, msgOption);
143 } else if (mode == OH_IPC_REQUEST_MODE_SYNC) {
144 return OH_IPC_CHECK_PARAM_ERROR;
145 } else {
146 OHOS::MessageParcel msgReply;
147 ret = proxy->remote->SendRequest(code, *data->msgParcel, msgReply, msgOption);
148 }
149 return ConvertSendRequestError(ret);
150 }
151
OH_IPCRemoteProxy_GetInterfaceDescriptor(OHIPCRemoteProxy * proxy,char ** descriptor,int32_t * len,OH_IPC_MemAllocator allocator)152 int OH_IPCRemoteProxy_GetInterfaceDescriptor(OHIPCRemoteProxy *proxy, char **descriptor, int32_t *len,
153 OH_IPC_MemAllocator allocator)
154 {
155 if (!IsIPCRemoteProxyValid(proxy, __func__)
156 || !IsMemoryParamsValid(descriptor, len, allocator, __func__)) {
157 return OH_IPC_CHECK_PARAM_ERROR;
158 }
159
160 std::u16string u16string(proxy->remote->GetInterfaceDescriptor());
161 std::string value = OHOS::Str16ToStr8(u16string);
162 if (u16string.length() != 0 && value.length() == 0) {
163 ZLOGE(LOG_LABEL, "Str16ToStr8 failed! u16string len: %{public}u, string len: %{public}u",
164 static_cast<uint32_t>(u16string.length()), static_cast<uint32_t>(value.length()));
165 return OH_IPC_PARCEL_READ_ERROR;
166 }
167
168 int memLength = static_cast<int>(value.length()) + 1;
169 *descriptor = static_cast<char*>(allocator(memLength));
170 if (*descriptor == nullptr) {
171 ZLOGE(LOG_LABEL, "memory allocator failed!");
172 return OH_IPC_MEM_ALLOCATOR_ERROR;
173 }
174 if (memcpy_s(*descriptor, memLength, value.c_str(), memLength) != EOK) {
175 ZLOGE(LOG_LABEL, "memcpy string failed");
176 return OH_IPC_PARCEL_READ_ERROR;
177 }
178 *len = memLength;
179 return OH_IPC_SUCCESS;
180 }
181
OH_IPCDeathRecipient_Create(OH_OnDeathRecipientCallback deathRecipientCallback,OH_OnDeathRecipientDestroyCallback destroyCallback,void * userData)182 OHIPCDeathRecipient* OH_IPCDeathRecipient_Create(OH_OnDeathRecipientCallback deathRecipientCallback,
183 OH_OnDeathRecipientDestroyCallback destroyCallback, void *userData)
184 {
185 if (deathRecipientCallback == nullptr) {
186 ZLOGE(LOG_LABEL, "args must not be null");
187 return nullptr;
188 }
189 OHOS::sptr<IPCDeathRecipient> recipient(new (std::nothrow) IPCDeathRecipient(
190 deathRecipientCallback, destroyCallback, userData));
191 if (recipient == nullptr) {
192 ZLOGE(LOG_LABEL, "create IPCDeathRecipient object failed");
193 return nullptr;
194 }
195 OHIPCDeathRecipient *deathRecipient = new (std::nothrow) OHIPCDeathRecipient();
196 if (deathRecipient == nullptr) {
197 ZLOGE(LOG_LABEL, "create OHIPCDeathRecipient failed");
198 return nullptr;
199 }
200 deathRecipient->recipient = recipient;
201 return deathRecipient;
202 }
203
OH_IPCDeathRecipient_Destroy(OHIPCDeathRecipient * recipient)204 void OH_IPCDeathRecipient_Destroy(OHIPCDeathRecipient *recipient)
205 {
206 if (recipient != nullptr) {
207 recipient->recipient = nullptr;
208 delete recipient;
209 }
210 }
211
OH_IPCRemoteProxy_AddDeathRecipient(OHIPCRemoteProxy * proxy,OHIPCDeathRecipient * recipient)212 int OH_IPCRemoteProxy_AddDeathRecipient(OHIPCRemoteProxy *proxy, OHIPCDeathRecipient *recipient)
213 {
214 if (!IsIPCRemoteProxyValid(proxy, __func__)
215 || recipient == nullptr
216 || recipient->recipient == nullptr) {
217 return OH_IPC_CHECK_PARAM_ERROR;
218 }
219
220 return proxy->remote->AddDeathRecipient(recipient->recipient) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
221 }
222
OH_IPCRemoteProxy_RemoveDeathRecipient(OHIPCRemoteProxy * proxy,OHIPCDeathRecipient * recipient)223 int OH_IPCRemoteProxy_RemoveDeathRecipient(OHIPCRemoteProxy *proxy, OHIPCDeathRecipient *recipient)
224 {
225 if (!IsIPCRemoteProxyValid(proxy, __func__)
226 || recipient == nullptr
227 || recipient->recipient == nullptr) {
228 return OH_IPC_CHECK_PARAM_ERROR;
229 }
230
231 return proxy->remote->RemoveDeathRecipient(recipient->recipient) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
232 }
233
OH_IPCRemoteProxy_IsRemoteDead(const OHIPCRemoteProxy * proxy)234 int OH_IPCRemoteProxy_IsRemoteDead(const OHIPCRemoteProxy *proxy)
235 {
236 if (!IsIPCRemoteProxyValid(proxy, __func__)) {
237 return 1;
238 }
239
240 return proxy->remote->IsObjectDead() ? 1 : 0;
241 }
242