• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #include <ipc_skeleton.h>
17 #include <iservice_registry.h>
18 #include <regex>
19 #include <string_ex.h>
20 #include <unistd.h>
21 #include <vector>
22 
23 #include "hdf_dump.h"
24 #include "hdf_core_log.h"
25 #include "hdf_object_manager.h"
26 #include "hdf_sbuf_ipc.h"
27 #include "hdf_remote_adapter.h"
28 #include "hdf_xcollie.h"
29 
30 #define HDF_LOG_TAG hdf_remote_adapter
31 
32 static constexpr int32_t THREAD_POOL_BASE_THREAD_COUNT = 5;
33 static int32_t g_remoteThreadMax = THREAD_POOL_BASE_THREAD_COUNT;
34 
HdfRemoteServiceStub(struct HdfRemoteService * service)35 HdfRemoteServiceStub::HdfRemoteServiceStub(struct HdfRemoteService *service)
36     : IPCObjectStub(std::u16string(u"")), service_(service)
37 {
38 }
39 
40 // LCOV_EXCL_START
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply,OHOS::MessageOption & option)41 int HdfRemoteServiceStub::OnRemoteRequest(uint32_t code,
42     OHOS::MessageParcel &data, OHOS::MessageParcel &reply, OHOS::MessageOption &option)
43 {
44     HDF_LOGD("OnRemoteRequest enter");
45     (void)option;
46 
47     int ret = HDF_FAILURE;
48     struct HdfSBuf *dataSbuf = ParcelToSbuf(&data);
49     struct HdfSBuf *replySbuf = ParcelToSbuf(&reply);
50 
51     std::shared_lock lock(mutex_);
52     if (service_ == nullptr) {
53         HDF_LOGE("service_ is nullptr");
54         HdfSbufRecycle(dataSbuf);
55         HdfSbufRecycle(replySbuf);
56         return HDF_ERR_INVALID_OBJECT;
57     }
58     struct HdfRemoteDispatcher *dispatcher = service_->dispatcher;
59     if (dispatcher != nullptr && dispatcher->Dispatch != nullptr) {
60         ret = dispatcher->Dispatch(reinterpret_cast<HdfRemoteService *>(service_->target), code, dataSbuf, replySbuf);
61     } else {
62         HDF_LOGE("dispatcher or dispatcher->Dispatch is null, flags is: %{public}d", option.GetFlags());
63     }
64 
65     HdfSbufRecycle(dataSbuf);
66     HdfSbufRecycle(replySbuf);
67     return ret;
68 }
69 // LCOV_EXCL_STOP
70 
HdfRemoteStubClearHolder()71 void HdfRemoteServiceStub::HdfRemoteStubClearHolder()
72 {
73     std::unique_lock lock(mutex_);
74     service_ = nullptr;
75 }
76 
~HdfRemoteServiceStub()77 HdfRemoteServiceStub::~HdfRemoteServiceStub()
78 {
79     HDF_LOGD("~HdfRemoteServiceStub");
80 }
81 
~HdfRemoteServiceHolder()82 HdfRemoteServiceHolder::~HdfRemoteServiceHolder()
83 {
84     HDF_LOGD("~HdfRemoteServiceHolder");
85 }
86 // LCOV_EXCL_START
Dump(int32_t fd,const std::vector<std::u16string> & args)87 int32_t HdfRemoteServiceStub::Dump(int32_t fd, const std::vector<std::u16string> &args)
88 {
89     return HdfDump(fd, args);
90 }
91 
HdfDeathNotifier(struct HdfRemoteService * service,struct HdfDeathRecipient * recipient)92 HdfDeathNotifier::HdfDeathNotifier(struct HdfRemoteService *service, struct HdfDeathRecipient *recipient)
93     : recipient_(recipient), service_(service)
94 {
95 }
96 
~HdfDeathNotifier()97 HdfDeathNotifier::~HdfDeathNotifier()
98 {
99 }
100 
OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> & object)101 void HdfDeathNotifier::OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> &object) /* who = 0 */
102 {
103     if (recipient_ != nullptr) {
104         recipient_->OnRemoteDied(recipient_, service_);
105     }
106 }
107 // LCOV_EXCL_STop
HdfRemoteAdapterOptionalDispatch(struct HdfRemoteService * service,int code,HdfSBuf * data,HdfSBuf * reply,bool sync)108 static int HdfRemoteAdapterOptionalDispatch(struct HdfRemoteService *service, int code,
109     HdfSBuf *data, HdfSBuf *reply, bool sync)
110 {
111     if (service == nullptr) {
112         return HDF_ERR_INVALID_PARAM;
113     }
114 
115     OHOS::MessageParcel *dataParcel = nullptr;
116     OHOS::MessageParcel *replyParcel = nullptr;
117 
118     if (reply == nullptr) {
119         static OHOS::MessageParcel dummyReply;
120         dummyReply.FlushBuffer();
121         replyParcel = &dummyReply;
122     } else if (SbufToParcel(reply, &replyParcel)) {
123 // LCOV_EXCL_START
124         HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
125         return HDF_ERR_INVALID_PARAM;
126     }
127 // LCOV_EXCL_STOP
128     if (SbufToParcel(data, &dataParcel)) {
129 // LCOV_EXCL_START
130         HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
131         return HDF_ERR_INVALID_PARAM;
132     }
133 // LCOV_EXCL_STOP
134     int flag = sync ? OHOS::MessageOption::TF_SYNC : OHOS::MessageOption::TF_ASYNC;
135     OHOS::MessageOption option(flag);
136     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
137     if (dataParcel != nullptr) {
138         OHOS::sptr<OHOS::IRemoteObject> remote = holder->remote_;
139         if (remote != nullptr) {
140             return remote->SendRequest(code, *dataParcel, *replyParcel, option);
141         }
142     }
143     return HDF_FAILURE;
144 }
145 
HdfRemoteAdapterDispatch(struct HdfRemoteService * service,int code,HdfSBuf * data,HdfSBuf * reply)146 static int HdfRemoteAdapterDispatch(struct HdfRemoteService *service,
147     int code, HdfSBuf *data, HdfSBuf *reply)
148 {
149     return HdfRemoteAdapterOptionalDispatch(service, code, data, reply, true);
150 }
151 // LCOV_EXCL_START
HdfRemoteAdapterDispatchAsync(struct HdfRemoteService * service,int code,HdfSBuf * data,HdfSBuf * reply)152 static int HdfRemoteAdapterDispatchAsync(struct HdfRemoteService *service,
153     int code, HdfSBuf *data, HdfSBuf *reply)
154 {
155     return HdfRemoteAdapterOptionalDispatch(service, code, data, reply, false);
156 }
157 // LCOV_EXCL_STOP
HdfRemoteServiceHolder()158 HdfRemoteServiceHolder::HdfRemoteServiceHolder() : remote_(nullptr), deathRecipient_(nullptr)
159 {
160     service_.object.objectId = HDF_OBJECT_ID_REMOTE_SERVICE;
161     service_.dispatcher = nullptr;
162     service_.target = nullptr;
163     service_.index = 0;
164 }
165 
SetInterfaceDescriptor(const char * desc)166 bool HdfRemoteServiceHolder::SetInterfaceDescriptor(const char *desc)
167 {
168     if (desc == nullptr) {
169         return false;
170     }
171     std::u16string newDesc = OHOS::Str8ToStr16(std::string(desc));
172 // LCOV_EXCL_START
173     if (newDesc.empty()) {
174         HDF_LOGE("failed to set interface des, error on cover str8 to str16, %{public}s", desc);
175         return false;
176     }
177 // LCOV_EXCL_STOP
178     descriptor_.assign(newDesc);
179     return true;
180 }
181 
HdfRemoteAdapterAddDeathRecipient(struct HdfRemoteService * service,struct HdfDeathRecipient * recipient)182 void HdfRemoteAdapterAddDeathRecipient(
183     struct HdfRemoteService *service, struct HdfDeathRecipient *recipient)
184 {
185     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
186     if (holder == nullptr) {
187         return;
188     }
189 // LCOV_EXCL_START
190     OHOS::sptr<OHOS::IRemoteObject> remote = holder->remote_;
191     if (remote == nullptr) {
192         return;
193     }
194     if (holder->deathRecipient_ != nullptr) {
195         remote->RemoveDeathRecipient(holder->deathRecipient_);
196     }
197     holder->deathRecipient_ = new HdfDeathNotifier(service, recipient);
198     remote->AddDeathRecipient(holder->deathRecipient_);
199 // LCOV_EXCL_STOP
200 }
201 
202 // LCOV_EXCL_START
HdfRemoteAdapterRemoveDeathRecipient(struct HdfRemoteService * service,const struct HdfDeathRecipient * recipient)203 void HdfRemoteAdapterRemoveDeathRecipient(
204     struct HdfRemoteService *service, const struct HdfDeathRecipient *recipient)
205 {
206     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
207     (void)recipient;
208     if (holder == nullptr) {
209         return;
210     }
211     OHOS::sptr<OHOS::IRemoteObject> remote = holder->remote_;
212     if (remote == nullptr) {
213         return;
214     }
215     if (holder->deathRecipient_ != nullptr) {
216         remote->RemoveDeathRecipient(holder->deathRecipient_);
217         holder->deathRecipient_ = nullptr;
218     }
219 }
220 // LCOV_EXCL_STOP
221 
HdfRemoteAdapterBind(OHOS::sptr<OHOS::IRemoteObject> binder)222 struct HdfRemoteService *HdfRemoteAdapterBind(OHOS::sptr<OHOS::IRemoteObject> binder)
223 {
224     struct HdfRemoteService *remoteService = nullptr;
225     static HdfRemoteDispatcher dispatcher = {
226         .Dispatch = HdfRemoteAdapterDispatch,
227         .DispatchAsync = HdfRemoteAdapterDispatchAsync,
228     };
229 
230     struct HdfRemoteServiceHolder *holder = new HdfRemoteServiceHolder();
231     if (holder != nullptr) {
232         holder->remote_ = binder;
233         remoteService = &holder->service_;
234         remoteService->dispatcher = &dispatcher;
235         remoteService->index = (uint64_t)binder.GetRefPtr();
236         return remoteService;
237     }
238     return nullptr;
239 }
240 
HdfRemoteAdapterObtain(void)241 struct HdfRemoteService *HdfRemoteAdapterObtain(void)
242 {
243     struct HdfRemoteServiceHolder *holder = new HdfRemoteServiceHolder();
244     holder->remote_ = new HdfRemoteServiceStub(&holder->service_);
245     return &holder->service_;
246 }
247 
HdfRemoteAdapterRecycle(struct HdfRemoteService * object)248 void HdfRemoteAdapterRecycle(struct HdfRemoteService *object)
249 {
250     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(object);
251     if (holder != nullptr) {
252         auto remote = holder->remote_;
253         if (remote != nullptr && !remote->IsProxyObject()) {
254             HdfRemoteServiceStub *stub = reinterpret_cast<HdfRemoteServiceStub *>(remote.GetRefPtr());
255             if (stub != nullptr) {
256                 stub->HdfRemoteStubClearHolder();
257             }
258         }
259         holder->service_.target = nullptr;
260         holder->service_.dispatcher = nullptr;
261         holder->descriptor_.clear();
262         holder->remote_ = nullptr;
263         delete holder;
264     }
265 }
266 // LCOV_EXCL_START
HdfRemoteAdapterAddService(const char * name,struct HdfRemoteService * service)267 int HdfRemoteAdapterAddService(const char *name, struct HdfRemoteService *service)
268 {
269     if (name == nullptr || service == nullptr) {
270         return HDF_ERR_INVALID_PARAM;
271     }
272 
273     OHOS::sptr<OHOS::IServiceRegistry> sr = OHOS::ServiceRegistry::GetInstance();
274     if (sr == nullptr) {
275         HDF_LOGE("failed to get service registry");
276         return HDF_FAILURE;
277     }
278     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
279     int ret = sr->AddService(OHOS::Str8ToStr16(name), holder->remote_);
280     if (ret == 0) {
281         (void)OHOS::IPCSkeleton::GetInstance().SetMaxWorkThreadNum(g_remoteThreadMax++);
282     }
283     return ret;
284 }
285 
HdfRemoteAdapterGetService(const char * name)286 struct HdfRemoteService *HdfRemoteAdapterGetService(const char *name)
287 {
288     if (name == nullptr) {
289         return nullptr;
290     }
291 
292     OHOS::sptr<OHOS::IServiceRegistry> sr = OHOS::ServiceRegistry::GetInstance();
293     if (sr == nullptr) {
294         HDF_LOGE("failed to get service registry");
295         return nullptr;
296     }
297     OHOS::sptr<OHOS::IRemoteObject> remote = sr->GetService(OHOS::Str8ToStr16(name));
298     if (remote != nullptr) {
299         return HdfRemoteAdapterBind(remote);
300     }
301     return nullptr;
302 }
303 // LCOV_EXCL_STOP
HdfRemoteAdapterAddSa(int32_t saId,struct HdfRemoteService * service)304 int HdfRemoteAdapterAddSa(int32_t saId, struct HdfRemoteService *service)
305 {
306     if (service == nullptr) {
307         return HDF_ERR_INVALID_PARAM;
308     }
309 
310     const int32_t waitTimes = 50;
311     const int32_t sleepInterval = 20000;
312     OHOS::sptr<OHOS::ISystemAbilityManager> saManager;
313     {
314         OHOS::HdfXCollie hdfXCollie("HdfRemoteAdapterAddSa_" + OHOS::ToString(saId) + "_get_samgr",
315             OHOS::DEFAULT_TIMEOUT_SECONDS, nullptr, nullptr, OHOS::HDF_XCOLLIE_FLAG_RECOVERY);
316 
317         for (uint32_t cnt = 0; cnt < waitTimes; ++cnt) {
318             HDF_LOGI("waiting for samgr... %{public}d", cnt);
319             saManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
320             if (saManager != nullptr) {
321                 HDF_LOGI("GetSystemAbilityManager success");
322                 break;
323             }
324 // LCOV_EXCL_START
325             HDF_LOGI("GetSystemAbilityManager failed, retry");
326             usleep(sleepInterval);
327         }
328 // LCOV_EXCL_STOP
329         if (saManager == nullptr) {
330             HDF_LOGE("failed to get sa manager, waiting timeout");
331             return HDF_FAILURE;
332         }
333     }
334     {
335         OHOS::HdfXCollie hdfXCollie("HdfRemoteAdapterAddSa_" + OHOS::ToString(saId) + "_add_sa",
336             OHOS::DEFAULT_TIMEOUT_SECONDS, nullptr, nullptr, OHOS::HDF_XCOLLIE_FLAG_RECOVERY);
337         struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
338 #ifdef WITH_SELINUX
339         OHOS::sptr<OHOS::IRemoteObject> remote = holder->remote_;
340         OHOS::IPCObjectStub *stub = reinterpret_cast<OHOS::IPCObjectStub *>(remote.GetRefPtr());
341         stub->SetRequestSidFlag(true);
342 #endif
343         int ret = HDF_FAILURE;
344         for (uint32_t cnt = 0; cnt < waitTimes; ++cnt) {
345             HDF_LOGI("waiting for addSa... %{public}d", cnt);
346             ret = saManager->AddSystemAbility(saId, holder->remote_);
347             if (ret == HDF_SUCCESS) {
348                 HDF_LOGI("addsa %{public}d, success", saId);
349                 break;
350             }
351             HDF_LOGI("AddSystemAbility failed, retry");
352             usleep(sleepInterval);
353         }
354         if (ret != HDF_SUCCESS) {
355             HDF_LOGE("failed to addSa, waiting timeout");
356             return ret;
357         }
358 
359         (void)OHOS::IPCSkeleton::GetInstance().SetMaxWorkThreadNum(g_remoteThreadMax++);
360     }
361     return HDF_SUCCESS;
362 }
363 
HdfRemoteAdapterGetSa(int32_t saId)364 struct HdfRemoteService *HdfRemoteAdapterGetSa(int32_t saId)
365 {
366     auto saManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
367     if (saManager == nullptr) {
368         HDF_LOGE("failed to get sa manager");
369         return nullptr;
370     }
371     OHOS::sptr<OHOS::IRemoteObject> remote = saManager->GetSystemAbility(saId);
372     constexpr int32_t waitTimes = 50;
373     constexpr int32_t sleepInterval = 20000;
374     int32_t timeout = waitTimes;
375     while (remote == nullptr && (timeout > 0)) {
376 // LCOV_EXCL_START
377         HDF_LOGD("waiting for saId %{public}d", saId);
378         usleep(sleepInterval);
379         remote = saManager->GetSystemAbility(saId);
380         timeout--;
381 // LCOV_EXCL_STOP
382     }
383     if (remote != nullptr) {
384         return HdfRemoteAdapterBind(remote);
385     } else {
386 // LCOV_EXCL_START
387         HDF_LOGE("failed to get sa %{public}d", saId);
388     }
389     return nullptr;
390 // LCOV_EXCL_STOP
391 }
392 
HdfRemoteAdapterSetInterfaceDesc(struct HdfRemoteService * service,const char * desc)393 bool HdfRemoteAdapterSetInterfaceDesc(struct HdfRemoteService *service, const char *desc)
394 {
395     if (service == nullptr || desc == nullptr) {
396         return false;
397     }
398     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
399     return holder->SetInterfaceDescriptor(desc);
400 }
401 
HdfRemoteAdapterWriteInterfaceToken(struct HdfRemoteService * service,struct HdfSBuf * data)402 bool HdfRemoteAdapterWriteInterfaceToken(struct HdfRemoteService *service, struct HdfSBuf *data)
403 {
404     if (service == nullptr || data == nullptr) {
405         return false;
406     }
407     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
408     OHOS::MessageParcel *parcel = nullptr;
409 
410     if (SbufToParcel(data, &parcel) != HDF_SUCCESS) {
411         HDF_LOGE("failed to write interface token, SbufToParcel error");
412         return false;
413     }
414 
415     if (holder->remote_ == nullptr) {
416         HDF_LOGE("failed to write interface token, holder->remote is nullptr");
417         return false;
418     }
419     if (holder->descriptor_.empty()) {
420         HDF_LOGE("failed to write interface token, empty token");
421         return false;
422     }
423     return parcel->WriteInterfaceToken(holder->descriptor_);
424 }
425 
CheckInterfaceTokenIngoreVersion(const std::string & client,const std::string & stub)426 static bool CheckInterfaceTokenIngoreVersion(const std::string &client, const std::string &stub)
427 {
428     std::vector<std::string> clientVec;
429     OHOS::SplitStr(client, ".", clientVec);
430     std::vector<std::string> stubVec;
431     OHOS::SplitStr(stub, ".", stubVec);
432     if (clientVec.size() != stubVec.size()) {
433         HDF_LOGE("%{public}s: client desc and stub desc have different size", __func__);
434         return false;
435     }
436     std::regex rVer("[V|v][0-9]+_[0-9]+");
437     for (size_t i = 0; i < stubVec.size(); i++) {
438         if (std::regex_match(stubVec[i], rVer)) {
439             continue;
440         }
441         if (clientVec[i] != stubVec[i]) {
442             HDF_LOGE("%{public}s: mismatch between client desc and stub desc", __func__);
443             return false;
444         }
445     }
446     return true;
447 }
448 
HdfRemoteAdapterCheckInterfaceToken(struct HdfRemoteService * service,struct HdfSBuf * data)449 bool HdfRemoteAdapterCheckInterfaceToken(struct HdfRemoteService *service, struct HdfSBuf *data)
450 {
451     if (service == nullptr || data == nullptr) {
452         return false;
453     }
454     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
455     if (holder->remote_ == nullptr) {
456         return false;
457     }
458     OHOS::MessageParcel *parcel = nullptr;
459 
460     if (SbufToParcel(data, &parcel) != HDF_SUCCESS) {
461         return false;
462     }
463     auto desc = parcel->ReadInterfaceToken();
464     if (desc.empty()) {
465         HDF_LOGE("failed to check interface, empty token");
466         return false;
467     }
468     std::string client = OHOS::Str16ToStr8(desc);
469     std::string stub = OHOS::Str16ToStr8(holder->descriptor_);
470     if (!CheckInterfaceTokenIngoreVersion(client, stub)) {
471         HDF_LOGE("calling unknown interface: %{public}s", client.c_str());
472         return false;
473     }
474     return true;
475 }
476 
HdfRemoteGetCallingPid(void)477 pid_t HdfRemoteGetCallingPid(void)
478 {
479     return OHOS::IPCSkeleton::GetCallingPid();
480 }
481 
HdfRemoteGetCallingUid(void)482 pid_t HdfRemoteGetCallingUid(void)
483 {
484     return OHOS::IPCSkeleton::GetCallingUid();
485 }
486 
HdfRemoteGetCallingSid(void)487 char *HdfRemoteGetCallingSid(void)
488 {
489     return strdup(OHOS::IPCSkeleton::GetCallingSid().c_str());
490 }
491 
HdfRemoteAdapterDefaultDispatch(struct HdfRemoteService * service,int code,struct HdfSBuf * data,struct HdfSBuf * reply)492 int HdfRemoteAdapterDefaultDispatch(struct HdfRemoteService *service,
493     int code, struct HdfSBuf *data, struct HdfSBuf *reply)
494 {
495     struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);
496     if (holder == nullptr) {
497         HDF_LOGE("%{public}s: failed to converts remote to holder", __func__);
498         return HDF_ERR_INVALID_PARAM;
499     }
500 
501     if (holder->remote_ == nullptr) {
502         HDF_LOGE("%{public}s: invaild holder, holder->remote is nullptr", __func__);
503         return HDF_ERR_INVALID_PARAM;
504     }
505 
506     OHOS::IPCObjectStub *stub = reinterpret_cast<OHOS::IPCObjectStub *>(holder->remote_.GetRefPtr());
507     if (stub == nullptr) {
508 // LCOV_EXCL_START
509         HDF_LOGE("%{public}s: failed to converts holder->remote to IPCObjectStub object", __func__);
510         return HDF_ERR_INVALID_PARAM;
511 // LCOV_EXCL_STOP
512     }
513 
514     OHOS::MessageParcel *dataParcel = nullptr;
515     OHOS::MessageParcel *replyParcel = nullptr;
516     OHOS::MessageOption option;
517 
518     if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
519 // LCOV_EXCL_START
520         HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
521         return HDF_ERR_INVALID_PARAM;
522 // LCOV_EXCL_STOP
523     }
524 
525     if (SbufToParcel(data, &replyParcel) != HDF_SUCCESS) {
526 // LCOV_EXCL_START
527         HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
528         return HDF_ERR_INVALID_PARAM;
529 // LCOV_EXCL_STOP
530     }
531 
532     return stub->IPCObjectStub::OnRemoteRequest(code, *dataParcel, *replyParcel, option);
533 }
534