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