1 /*
2 * Copyright (C) 2021-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 #ifndef OHOS_IPC_DBINDER_BASE_INVOKER_OBJECT_H
17 #define OHOS_IPC_DBINDER_BASE_INVOKER_OBJECT_H
18
19 #include "dbinder_base_invoker_define.h"
20
21 namespace OHOS {
22
TranslateBinderType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)23 template<class T> uint32_t DBinderBaseInvoker<T>::TranslateBinderType(
24 flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session)
25 {
26 std::shared_ptr<T> sessionOfPeer = CreateServerSessionObject(binderObject->cookie, session);
27 if (sessionOfPeer == nullptr) {
28 ZLOGE(LOG_LABEL, "send an wrong stub object");
29 return 0;
30 }
31 binderObject->hdr.type = BINDER_TYPE_REMOTE_HANDLE;
32 binderObject->cookie = IRemoteObject::IF_PROT_DATABUS;
33 binderObject->binder = 0;
34 return FlattenSession(sessionOffset, sessionOfPeer, SUPPORT_TOKENID_VERSION_NUM);
35 }
36
ClearBinderType(flat_binder_object * binderObject)37 template<class T> void DBinderBaseInvoker<T>::ClearBinderType(flat_binder_object *binderObject)
38 {
39 binderObject->hdr.type = BINDER_TYPE_INVALID_BINDER;
40 binderObject->cookie = IRemoteObject::IF_PROT_ERROR;
41 binderObject->binder = 0;
42 }
43
TranslateHandleType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)44 template<class T> uint32_t DBinderBaseInvoker<T>::TranslateHandleType(
45 flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session)
46 {
47 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
48 if (current == nullptr) {
49 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
50 return 0;
51 }
52 std::shared_ptr<T> sessionOfPeer = nullptr;
53 if (binderObject->cookie == IRemoteObject::IF_PROT_DATABUS) {
54 sessionOfPeer = QuerySessionOfBinderProxy(binderObject->handle, session);
55 } else if (binderObject->cookie == IRemoteObject::IF_PROT_BINDER) {
56 sessionOfPeer = NewSessionOfBinderProxy(binderObject->handle, session);
57 }
58 if (sessionOfPeer == nullptr) {
59 ZLOGE(LOG_LABEL, "send an wrong dbinder object");
60 return 0;
61 }
62
63 binderObject->hdr.type = BINDER_TYPE_REMOTE_HANDLE;
64 return FlattenSession(sessionOffset, sessionOfPeer, SUPPORT_TOKENID_VERSION_NUM);
65 }
66
ClearHandleType(flat_binder_object * binderObject)67 template<class T> void DBinderBaseInvoker<T>::ClearHandleType(flat_binder_object *binderObject)
68 {
69 binderObject->hdr.type = BINDER_TYPE_INVALID_HANDLE;
70 binderObject->cookie = IRemoteObject::IF_PROT_ERROR;
71 binderObject->binder = 0;
72 }
73
TranslateRemoteHandleType(flat_binder_object * binderObject,char * sessionOffset,uint32_t binderVersion)74 template<class T> bool DBinderBaseInvoker<T>::TranslateRemoteHandleType(
75 flat_binder_object *binderObject, char *sessionOffset, uint32_t binderVersion)
76 {
77 std::shared_ptr<T> sessionOfPeer = nullptr;
78 if (binderObject->cookie == IRemoteObject::IF_PROT_DATABUS ||
79 binderObject->cookie == IRemoteObject::IF_PROT_BINDER) {
80 sessionOfPeer = UnFlattenSession(sessionOffset, binderVersion);
81 }
82 if (sessionOfPeer == nullptr) {
83 ZLOGE(LOG_LABEL, "send a wrong dbinder object");
84 return false;
85 }
86
87 // 1. If we find matched session, we need to first take its ownership in case of being erased
88 // during proxy initialization
89 // 2. If translate remote handle type concurrently, we may alloc two new handle, and open session
90 // with the same sessionName and deviceId. thus get the same softbus session. this is OK because if
91 // one proxy is reclaimed, we will close session when it is no longer used
92 uint32_t handle = QueryHandleBySession(sessionOfPeer);
93 if (handle == 0) {
94 handle = MakeRemoteHandle(sessionOfPeer);
95 ZLOGI(LOG_LABEL, "create new handle:%{public}u", handle);
96 if (handle == 0) {
97 ZLOGE(LOG_LABEL, "failed to create new handle");
98 return false;
99 }
100 }
101 // If any error occurred before, hdr.type was still BINDER_TYPE_REMOTE_HANDLE
102 // Thus later UnFlattenObject will enter default case and return null
103 binderObject->hdr.type = BINDER_TYPE_HANDLE;
104 binderObject->handle = handle;
105 return true;
106 }
107
108 /* check data parcel contains object, if yes, get its session as payload of socket packet
109 * if translate any object failed, discard this parcel and do NOT send this parcel to remote
110 */
111 template<class T>
IRemoteObjectTranslateWhenSend(char * dataBuffer,binder_size_t bufferSize,MessageParcel & data,uint32_t socketId,std::shared_ptr<T> sessionObject)112 bool DBinderBaseInvoker<T>::IRemoteObjectTranslateWhenSend(char *dataBuffer, binder_size_t bufferSize,
113 MessageParcel &data, uint32_t socketId, std::shared_ptr<T> sessionObject)
114 {
115 if (data.GetOffsetsSize() <= 0 || dataBuffer == nullptr) {
116 return true;
117 }
118
119 uint32_t totalSize = 0;
120 binder_size_t *binderObjectsOffsets = reinterpret_cast<binder_size_t *>(data.GetObjectOffsets());
121 uint32_t offsetOfSession = bufferSize + data.GetOffsetsSize() * sizeof(binder_size_t);
122 char *flatOffset = dataBuffer + offsetOfSession;
123
124 for (size_t i = 0; i < data.GetOffsetsSize(); i++) {
125 auto binderObject = reinterpret_cast<flat_binder_object *>(dataBuffer + *(binderObjectsOffsets + i));
126 switch (binderObject->hdr.type) {
127 case BINDER_TYPE_BINDER: {
128 uint32_t flatSize = TranslateBinderType(binderObject, flatOffset + totalSize, sessionObject);
129 if (flatSize == 0) {
130 ZLOGE(LOG_LABEL, "send an wrong stub object");
131 return false;
132 }
133 totalSize += flatSize;
134 break;
135 }
136 case BINDER_TYPE_HANDLE: {
137 uint32_t flatSize = TranslateHandleType(binderObject, flatOffset + totalSize, sessionObject);
138 if (flatSize == 0) {
139 ZLOGE(LOG_LABEL, "send an wrong dbinder object");
140 return false;
141 }
142 totalSize += flatSize;
143 break;
144 }
145 case BINDER_TYPE_FD: {
146 binderObject->hdr.type = BINDER_TYPE_FDR;
147 binderObject->handle = -1;
148 break;
149 }
150 default: {
151 ZLOGE(LOG_LABEL, "do not support this type:%{public}u of translation", binderObject->hdr.type);
152 // do nothing
153 break;
154 }
155 }
156 }
157 return true;
158 }
159
160 /* if translate any object failed, should translate next object flush it */
161 template<class T>
IRemoteObjectTranslateWhenRcv(char * dataBuffer,binder_size_t bufferSize,MessageParcel & data,uint32_t socketId,std::shared_ptr<T> sessionObject)162 bool DBinderBaseInvoker<T>::IRemoteObjectTranslateWhenRcv(char *dataBuffer, binder_size_t bufferSize,
163 MessageParcel &data, uint32_t socketId, std::shared_ptr<T> sessionObject)
164 {
165 if (data.GetOffsetsSize() <= 0 || dataBuffer == nullptr) {
166 return true;
167 }
168 binder_size_t *binderObjectsOffsets = reinterpret_cast<binder_size_t *>(data.GetObjectOffsets());
169 uint32_t offsetOfSession = bufferSize + data.GetOffsetsSize() * sizeof(binder_size_t);
170 char *flatOffset = dataBuffer + offsetOfSession;
171
172 for (size_t i = 0; i < data.GetOffsetsSize(); i++) {
173 auto binderObject = reinterpret_cast<flat_binder_object *>(dataBuffer + *(binderObjectsOffsets + i));
174 switch (binderObject->hdr.type) {
175 case BINDER_TYPE_BINDER: {
176 ClearBinderType(binderObject);
177 ZLOGE(LOG_LABEL, "receive an wrong stub object");
178 break;
179 }
180 case BINDER_TYPE_HANDLE: {
181 ClearHandleType(binderObject);
182 ZLOGE(LOG_LABEL, "receive an wrong proxy object");
183 break;
184 }
185 case BINDER_TYPE_REMOTE_HANDLE: {
186 if (TranslateRemoteHandleType(binderObject, flatOffset + i * T::GetFlatSessionLen(),
187 SUPPORT_TOKENID_VERSION_NUM) != true) {
188 ZLOGE(LOG_LABEL, "receive an wrong dbiner object");
189 // do nothing, should translate other parcel object, such as fd should set to -1
190 }
191 break;
192 }
193 case BINDER_TYPE_FD: {
194 binderObject->hdr.type = BINDER_TYPE_FDR;
195 binderObject->handle = -1;
196 break;
197 }
198 case BINDER_TYPE_FDR: {
199 if (!TranslateRawData(dataBuffer, data, socketId)) {
200 ZLOGE(LOG_LABEL, "fail to translate big raw data");
201 // do nothing
202 }
203 binderObject->handle = -1;
204 break;
205 }
206 default: {
207 ZLOGE(LOG_LABEL, "do not support this type:%{public}u of translation", binderObject->hdr.type);
208 binderObject->hdr.type = BINDER_TYPE_INVALID_TYPE;
209 // do nothing
210 break;
211 }
212 }
213 }
214 return true;
215 }
216
GetSessionObject(uint32_t handle,uint32_t socketId)217 template <class T> std::shared_ptr<T> DBinderBaseInvoker<T>::GetSessionObject(uint32_t handle, uint32_t socketId)
218 {
219 if (handle != 0) {
220 /* transact case */
221 return QueryServerSessionObject(handle);
222 } else {
223 /* reply case */
224 return QueryClientSessionObject(socketId);
225 }
226 }
227
GetUniqueSeqNumber(int cmd)228 template <class T> uint64_t DBinderBaseInvoker<T>::GetUniqueSeqNumber(int cmd)
229 {
230 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
231 if (current == nullptr) {
232 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
233 return 0;
234 }
235
236 if (cmd == BC_TRANSACTION) {
237 return current->GetSeqNumber();
238 } else if (cmd == BC_REPLY) {
239 /* use sender sequence number */
240 return GetSeqNum();
241 } else {
242 return 0;
243 }
244 }
245
246 template <class T>
ConstructTransData(MessageParcel & data,dbinder_transaction_data & transData,size_t totalSize,uint64_t seqNum,int cmd,__u32 code,__u32 flags)247 void DBinderBaseInvoker<T>::ConstructTransData(MessageParcel &data, dbinder_transaction_data &transData,
248 size_t totalSize, uint64_t seqNum, int cmd, __u32 code, __u32 flags)
249 {
250 transData.sizeOfSelf = totalSize;
251 transData.magic = DBINDER_MAGICWORD;
252 transData.version = SUPPORT_TOKENID_VERSION_NUM;
253 transData.cmd = cmd;
254 transData.code = code;
255 transData.flags = flags;
256 transData.cookie = 0;
257 transData.seqNumber = seqNum;
258 transData.buffer_size = 0;
259 transData.offsets_size = 0;
260 transData.offsets = 0;
261 }
262
263 template <class T>
TranslateRawData(char * dataBuffer,MessageParcel & data,uint32_t socketId)264 bool DBinderBaseInvoker<T>::TranslateRawData(char *dataBuffer, MessageParcel &data, uint32_t socketId)
265 {
266 if (data.GetOffsetsSize() <= 0 || socketId == 0) {
267 ZLOGI(LOG_LABEL, "no raw data to translate.");
268 return true;
269 }
270
271 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
272 if (current == nullptr) {
273 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
274 return false;
275 }
276 std::shared_ptr<InvokerRawData> receivedRawData = current->QueryRawData(socketId);
277 if (receivedRawData == nullptr) {
278 ZLOGE(LOG_LABEL, "cannot found rawData according to the socketId:%{public}u", socketId);
279 return false;
280 }
281 std::shared_ptr<char> rawData = receivedRawData->GetData();
282 size_t rawSize = receivedRawData->GetSize();
283 current->DetachRawData(socketId);
284 if (!data.RestoreRawData(rawData, rawSize)) {
285 ZLOGE(LOG_LABEL, "found rawData, but cannot restore them, socketId:%{public}u", socketId);
286 return false;
287 }
288 return true;
289 }
290
291 template <class T>
MoveTransData2Buffer(std::shared_ptr<T> sessionObject,std::shared_ptr<dbinder_transaction_data> transData)292 bool DBinderBaseInvoker<T>::MoveTransData2Buffer(std::shared_ptr<T> sessionObject,
293 std::shared_ptr<dbinder_transaction_data> transData)
294 {
295 std::shared_ptr<BufferObject> sessionBuff = sessionObject->GetSessionBuff();
296 if (sessionBuff == nullptr) {
297 ZLOGE(LOG_LABEL, "get session buffer fail");
298 return false;
299 }
300 if (transData == nullptr) {
301 ZLOGE(LOG_LABEL, "transData is nullptr");
302 return false;
303 }
304 uint32_t sendSize = transData->sizeOfSelf;
305 char *sendBuffer = sessionBuff->GetSendBufferAndLock(sendSize);
306 /* session buffer contain mutex, need release mutex */
307 if (sendBuffer == nullptr) {
308 ZLOGE(LOG_LABEL, "buffer alloc failed in session");
309 return false;
310 }
311
312 sessionBuff->UpdateSendBuffer(sendSize);
313 ssize_t writeCursor = sessionBuff->GetSendBufferWriteCursor();
314 ssize_t readCursor = sessionBuff->GetSendBufferReadCursor();
315 if (writeCursor < 0 || readCursor < 0 || static_cast<uint32_t>(writeCursor) > sessionBuff->GetSendBufferSize() ||
316 sendSize > sessionBuff->GetSendBufferSize() - static_cast<uint32_t>(writeCursor)) {
317 sessionBuff->ReleaseSendBufferLock();
318 ZLOGE(LOG_LABEL, "sender's data is large than idle buffer, writecursor:%{public}zd readcursor:%{public}zd,\
319 sendSize:%{public}u bufferSize:%{public}u",
320 writeCursor, readCursor, sendSize, sessionBuff->GetSendBufferSize());
321 return false;
322 }
323 if (memcpy_s(sendBuffer + writeCursor, sendSize, transData.get(), sendSize)) {
324 sessionBuff->ReleaseSendBufferLock();
325 ZLOGE(LOG_LABEL, "fail to copy from tr to sendBuffer, parcelSize:%{public}u", sendSize);
326 return false;
327 }
328
329 writeCursor += static_cast<ssize_t>(sendSize);
330 sessionBuff->SetSendBufferWriteCursor(writeCursor);
331 sessionBuff->SetSendBufferReadCursor(readCursor);
332 sessionBuff->ReleaseSendBufferLock();
333 return true;
334 }
335
336 template <class T>
HandleReply(uint64_t seqNumber,MessageParcel * reply,std::shared_ptr<ThreadMessageInfo> messageInfo)337 int DBinderBaseInvoker<T>::HandleReply(uint64_t seqNumber, MessageParcel *reply,
338 std::shared_ptr<ThreadMessageInfo> messageInfo)
339 {
340 if (reply == nullptr) {
341 ZLOGE(LOG_LABEL, "no need reply, free the buffer");
342 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_NO_NEED_REPLY, __FUNCTION__);
343 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
344 }
345
346 if (messageInfo == nullptr) {
347 ZLOGE(LOG_LABEL, "receive buffer is nullptr");
348 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RECEIVE_BUFFER_NULL, __FUNCTION__);
349 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
350 }
351
352 if (messageInfo->flags & MessageOption::TF_STATUS_CODE) {
353 int32_t err = static_cast<int32_t>(messageInfo->offsetsSize);
354 return err;
355 }
356 if (messageInfo->buffer == nullptr) {
357 ZLOGE(LOG_LABEL, "need reply message, but buffer is nullptr");
358 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_BUFFER_NULL, __FUNCTION__);
359 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
360 }
361 auto allocator = new (std::nothrow) DBinderRecvAllocator();
362 if (allocator == nullptr) {
363 ZLOGE(LOG_LABEL, "create DBinderRecvAllocator object failed");
364 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CREATE_RECV_ALLOCATOR_FAIL, __FUNCTION__);
365 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
366 }
367 if (!reply->SetAllocator(allocator)) {
368 ZLOGE(LOG_LABEL, "SetAllocator failed");
369 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SET_ALLOCATOR_FAIL, __FUNCTION__);
370 delete allocator;
371 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
372 }
373 reply->ParseFrom(reinterpret_cast<uintptr_t>(messageInfo->buffer), messageInfo->bufferSize);
374
375 if (messageInfo->offsetsSize > 0) {
376 reply->InjectOffsets(
377 reinterpret_cast<binder_uintptr_t>(reinterpret_cast<char *>(messageInfo->buffer) + messageInfo->offsets),
378 messageInfo->offsetsSize / sizeof(binder_size_t));
379 }
380
381 if (!IRemoteObjectTranslateWhenRcv(reinterpret_cast<char *>(messageInfo->buffer), messageInfo->bufferSize, *reply,
382 messageInfo->socketId, nullptr)) {
383 ZLOGE(LOG_LABEL, "translate object failed, socketId:%{public}u", messageInfo->socketId);
384 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_TRANSLATE_OBJECT_FAIL, __FUNCTION__);
385 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
386 }
387
388 return ERR_NONE;
389 }
390
Dealloc(void * data)391 template <class T> void DBinderBaseInvoker<T>::DBinderSendAllocator::Dealloc(void *data) {}
392
Dealloc(void * data)393 template <class T> void DBinderBaseInvoker<T>::DBinderRecvAllocator::Dealloc(void *data)
394 {
395 delete[](unsigned char *) data;
396 }
397
398 template <class T>
WaitForReply(uint64_t seqNumber,MessageParcel * reply,uint32_t handle,int userWaitTime)399 int DBinderBaseInvoker<T>::WaitForReply(uint64_t seqNumber, MessageParcel *reply, uint32_t handle, int userWaitTime)
400 {
401 /* if reply == nullptr, this is a one way message */
402 if (reply == nullptr) {
403 return NO_ERROR;
404 }
405
406 std::shared_ptr<ThreadMessageInfo> messageInfo = MakeThreadMessageInfo(handle);
407 if (messageInfo == nullptr) {
408 ZLOGE(LOG_LABEL, "make thread message info failed, handle:%{public}u seq:%{public}" PRIu64,
409 handle, seqNumber);
410 return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
411 }
412
413 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
414 if (current == nullptr) {
415 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr, handle:%{public}u seq:%{public}" PRIu64,
416 handle, seqNumber);
417 return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
418 }
419 /* wait for reply */
420 if (!current->AddSendThreadInWait(seqNumber, messageInfo, userWaitTime)) {
421 current->EraseThreadBySeqNumber(seqNumber);
422 ZLOGE(LOG_LABEL, "sender thread wait reply message time out, "
423 "waitTime:%{public}d handle:%{public}u seq:%{public}" PRIu64, userWaitTime, handle, seqNumber);
424 return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
425 }
426
427 int32_t err = HandleReply(seqNumber, reply, messageInfo);
428 current->EraseThreadBySeqNumber(seqNumber);
429 messageInfo->buffer = nullptr;
430 messageInfo->ready = false;
431 return err;
432 }
433
AddDeathRecipient(int32_t handle,void * cookie)434 template <class T> bool DBinderBaseInvoker<T>::AddDeathRecipient(int32_t handle, void *cookie)
435 {
436 return true;
437 }
438
RemoveDeathRecipient(int32_t handle,void * cookie)439 template <class T> bool DBinderBaseInvoker<T>::RemoveDeathRecipient(int32_t handle, void *cookie)
440 {
441 return true;
442 }
443
StartProcessLoop(int32_t socketId,const char * buffer,uint32_t size)444 template <class T> void DBinderBaseInvoker<T>::StartProcessLoop(int32_t socketId, const char *buffer, uint32_t size)
445 {
446 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
447 if (current == nullptr) {
448 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
449 return;
450 }
451 std::shared_ptr<ThreadProcessInfo> processInfo = MakeThreadProcessInfo(socketId, buffer, size);
452 if (processInfo == nullptr) {
453 ZLOGE(LOG_LABEL, "processInfo is nullptr");
454 return;
455 }
456 std::thread::id threadId = current->GetIdleDataThread();
457 if (threadId == std::thread::id()) {
458 bool result = CreateProcessThread();
459 if (!result) {
460 int socketThreadNum = current->GetSocketTotalThreadNum();
461 ZLOGE(LOG_LABEL, "create IO thread failed, current socket thread num:%{public}d socketId:%{public}d",
462 socketThreadNum, socketId);
463 /* thread create too much, wait some thread be idle */
464 }
465 do {
466 /* no IO thread in idle state, wait a monent */
467 std::this_thread::sleep_for(std::chrono::milliseconds(1));
468 } while ((threadId = current->GetIdleDataThread()) == std::thread::id());
469 }
470
471 current->AddDataInfoToThread(threadId, processInfo);
472 current->WakeUpDataThread(threadId);
473 return;
474 }
475
MakeThreadMessageInfo(int32_t socketId)476 template <class T> std::shared_ptr<ThreadMessageInfo> DBinderBaseInvoker<T>::MakeThreadMessageInfo(int32_t socketId)
477 {
478 std::shared_ptr<ThreadMessageInfo> messageInfo = std::make_shared<struct ThreadMessageInfo>();
479 if (messageInfo == nullptr) {
480 ZLOGE(LOG_LABEL, "make ThreadMessageInfo fail");
481 return nullptr;
482 }
483
484 messageInfo->buffer = nullptr;
485 messageInfo->offsets = 0;
486 messageInfo->socketId = static_cast<uint32_t>(socketId);
487 messageInfo->ready = false;
488 return messageInfo;
489 }
490
MakeRemoteHandle(std::shared_ptr<T> session)491 template<class T> uint32_t DBinderBaseInvoker<T>::MakeRemoteHandle(std::shared_ptr<T> session)
492 {
493 if (session == nullptr) {
494 ZLOGE(LOG_LABEL, "session is nullptr");
495 return 0;
496 }
497 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
498 if (current == nullptr) {
499 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
500 return 0;
501 }
502
503 if (!UpdateClientSession(session)) {
504 ZLOGE(LOG_LABEL, "open session failed");
505 return 0;
506 }
507 uint32_t handle = current->GetDBinderIdleHandle(session);
508 if (handle == 0) {
509 ZLOGE(LOG_LABEL, "get dbinder handle failed");
510 if (current->QuerySessionByInfo(session->GetServiceName(), session->GetDeviceId()) == nullptr) {
511 session->CloseDatabusSession();
512 }
513 return 0;
514 }
515 return handle;
516 }
517
518 } // namespace OHOS
519 #endif // OHOS_IPC_DBINDER_BASE_INVOKER_OBJECT_H