• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_H
17 #define OHOS_IPC_DBINDER_BASE_INVOKER_H
18 
19 #include <unistd.h>
20 #include <cinttypes>
21 #include <memory>
22 #include <sys/types.h>
23 #include "securec.h"
24 #include "sys_binder.h"
25 #include "iremote_invoker.h"
26 #include "invoker_factory.h"
27 
28 #include "ipc_object_stub.h"
29 #include "ipc_object_proxy.h"
30 #include "ipc_process_skeleton.h"
31 #include "ipc_thread_skeleton.h"
32 #include "ipc_skeleton.h"
33 #include "ipc_debug.h"
34 #include "hitrace_invoker.h"
35 #include "dbinder_error_code.h"
36 #include "log_tags.h"
37 
38 namespace OHOS {
39 using namespace OHOS::HiviewDFX;
40 
41 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "DBinderBaseInvoker" };
42 
43 template <class T> class DBinderBaseInvoker : public IRemoteInvoker {
44 public:
45     class DBinderSendAllocator : public DefaultAllocator {
46         void Dealloc(void *data) override;
47 
48         friend DBinderBaseInvoker;
49     };
50 
51     class DBinderRecvAllocator : public DefaultAllocator {
52         void Dealloc(void *data) override;
53 
54         friend DBinderBaseInvoker;
55     };
56 
57     virtual ~DBinderBaseInvoker() = default;
58     virtual std::shared_ptr<T> QueryServerSessionObject(uint32_t handle) = 0;
59     virtual bool UpdateClientSession(std::shared_ptr<T> sessionObject) = 0;
60 
61     virtual int SendRequest(int32_t handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
62         MessageOption &option) override;
63     virtual bool AddDeathRecipient(int32_t handle, void *cookie) override;
64     virtual bool RemoveDeathRecipient(int32_t handle, void *cookie) override;
65     virtual bool SetMaxWorkThread(int maxThreadNum) override;
66     virtual int SendReply(MessageParcel &reply, uint32_t flags, int32_t result) override;
67     virtual bool PingService(int32_t handle) override;
68     virtual sptr<IRemoteObject> GetSAMgrObject() override;
69     virtual bool SetRegistryObject(sptr<IRemoteObject> &object) override;
70     virtual void FreeBuffer(void *data) override;
71     virtual std::shared_ptr<T> WriteTransaction(int cmd, uint32_t flags, int32_t handle, int32_t socketId,
72         uint32_t code, MessageParcel &data, uint64_t &seqNumber, int status);
73     virtual int SendOrWaitForCompletion(int userWaitTime, uint64_t seqNumber, std::shared_ptr<T> sessionOfPeer,
74         MessageParcel *reply = nullptr);
75     virtual void OnTransaction(std::shared_ptr<ThreadProcessInfo> processInfo);
76     virtual void StartProcessLoop(uint32_t handle, const char *buffer, uint32_t size);
77     virtual uint32_t QueryHandleBySession(std::shared_ptr<T> session) = 0;
78     virtual std::shared_ptr<T> QueryClientSessionObject(uint32_t databusHandle) = 0;
79     virtual std::shared_ptr<T> NewSessionOfBinderProxy(uint32_t handle, std::shared_ptr<T> session) = 0;
80     virtual std::shared_ptr<T> QuerySessionOfBinderProxy(uint32_t handle, std::shared_ptr<T> session) = 0;
81     virtual std::shared_ptr<T> CreateServerSessionObject(binder_uintptr_t binder, std::shared_ptr<T> sessionObject) = 0;
82     virtual uint32_t FlattenSession(char *sessionOffset, const std::shared_ptr<T> connectSession,
83         uint32_t binderVersion) = 0;
84     virtual std::shared_ptr<T> UnFlattenSession(char *sessionOffset, uint32_t binderVersion) = 0;
85     virtual int OnSendMessage(std::shared_ptr<T> sessionOfPeer) = 0;
86     virtual bool CreateProcessThread() = 0;
87     virtual uint64_t GetSeqNum() const = 0;
88     virtual void SetSeqNum(uint64_t seq) = 0;
89     virtual uint32_t GetClientFd() const = 0;
90     virtual void SetClientFd(uint32_t fd) = 0;
91     virtual void SetCallerPid(pid_t pid) = 0;
92     virtual void SetCallerUid(pid_t uid) = 0;
93     virtual void SetStatus(uint32_t status) = 0;
94     virtual void SetCallerDeviceID(const std::string &deviceId) = 0;
95     virtual void SetCallerTokenID(const uint32_t tokenId) = 0;
96     virtual int CheckAndSetCallerInfo(uint32_t listenFd, uint64_t stubIndex) = 0;
97     virtual int OnSendRawData(std::shared_ptr<T> session, const void *data, size_t size) = 0;
98     bool CheckTransactionData(const dbinder_transaction_data *tr) const;
99     std::mutex &GetObjectMutex();
100 
101 private:
102     uint32_t TranslateBinderType(flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session);
103     uint32_t TranslateHandleType(flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session);
104     void ClearBinderType(flat_binder_object *binderObject);
105     void ClearHandleType(flat_binder_object *binderObject);
106     bool TranslateRemoteHandleType(flat_binder_object *binderObject, char *sessionOffset, uint32_t binderVersion);
107     int HandleReply(uint64_t seqNumber, MessageParcel *reply, std::shared_ptr<ThreadMessageInfo> messageInfo);
108     int WaitForReply(uint64_t seqNumber, MessageParcel *reply, uint32_t handle, int userWaitTime);
109     void ProcessTransaction(dbinder_transaction_data *tr, uint32_t listenFd);
110     void ProcessReply(dbinder_transaction_data *tr, uint32_t listenFd);
111     bool IRemoteObjectTranslateWhenSend(char *dataBuffer, binder_size_t bufferSize, MessageParcel &data,
112         uint32_t socketId, std::shared_ptr<T> sessionObject);
113     bool IRemoteObjectTranslateWhenRcv(char *dataBuffer, binder_size_t bufferSize, MessageParcel &data,
114         uint32_t socketId, std::shared_ptr<T> sessionObject);
115     bool TranslateRawData(char *dataBuffer, MessageParcel &data, uint32_t socketId);
116     std::shared_ptr<T> GetSessionObject(uint32_t handle, uint32_t socketId);
117     uint64_t GetUniqueSeqNumber(int cmd);
118     void ConstructTransData(MessageParcel &data, dbinder_transaction_data &transData, size_t totalSize,
119         uint64_t seqNum, int cmd, __u32 code, __u32 flags);
120     bool ProcessRawData(std::shared_ptr<T> sessionObject, MessageParcel &data, uint64_t seqNum);
121     std::shared_ptr<dbinder_transaction_data> ProcessNormalData(std::shared_ptr<T> sessionObject, MessageParcel &data,
122         int32_t handle, int32_t socketId, uint64_t seqNum, int cmd, __u32 code, __u32 flags, int status);
123     bool MoveTransData2Buffer(std::shared_ptr<T> sessionObject, std::shared_ptr<dbinder_transaction_data> transData);
124     bool MoveMessageParcel2TransData(MessageParcel &data, std::shared_ptr<T> sessionObject,
125         std::shared_ptr<dbinder_transaction_data> transData, int32_t socketId, int status);
126     std::shared_ptr<ThreadProcessInfo> MakeThreadProcessInfo(uint32_t handle, const char *buffer, uint32_t size);
127     std::shared_ptr<ThreadMessageInfo> MakeThreadMessageInfo(uint32_t handle);
128     uint32_t MakeRemoteHandle(std::shared_ptr<T> session);
129 
130 private:
131     std::mutex objectMutex_;
132 };
133 
134 template<class T>
TranslateBinderType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)135 uint32_t DBinderBaseInvoker<T>::TranslateBinderType(flat_binder_object *binderObject, char *sessionOffset,
136     std::shared_ptr<T> session)
137 {
138     std::shared_ptr<T> sessionOfPeer = CreateServerSessionObject(binderObject->cookie, session);
139     if (sessionOfPeer == nullptr) {
140         ZLOGE(LOG_LABEL, "send an wrong stub object");
141         return 0;
142     }
143     binderObject->hdr.type = BINDER_TYPE_REMOTE_HANDLE;
144     binderObject->cookie = IRemoteObject::IF_PROT_DATABUS;
145     binderObject->binder = 0;
146     return FlattenSession(sessionOffset, sessionOfPeer, SUPPORT_TOKENID_VERSION_NUM);
147 }
148 
149 template<class T>
ClearBinderType(flat_binder_object * binderObject)150 void DBinderBaseInvoker<T>::ClearBinderType(flat_binder_object *binderObject)
151 {
152     binderObject->hdr.type = BINDER_TYPE_INVALID_BINDER;
153     binderObject->cookie = IRemoteObject::IF_PROT_ERROR;
154     binderObject->binder = 0;
155 }
156 
157 template<class T>
TranslateHandleType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)158 uint32_t DBinderBaseInvoker<T>::TranslateHandleType(flat_binder_object *binderObject, char *sessionOffset,
159     std::shared_ptr<T> session)
160 {
161     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
162     if (current == nullptr) {
163         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
164         return 0;
165     }
166     std::shared_ptr<T> sessionOfPeer = nullptr;
167     if (binderObject->cookie == IRemoteObject::IF_PROT_DATABUS) {
168         sessionOfPeer = QuerySessionOfBinderProxy(binderObject->handle, session);
169     } else if (binderObject->cookie == IRemoteObject::IF_PROT_BINDER) {
170         sessionOfPeer = NewSessionOfBinderProxy(binderObject->handle, session);
171     }
172     if (sessionOfPeer == nullptr) {
173         ZLOGE(LOG_LABEL, "send an wrong dbinder object");
174         return 0;
175     }
176 
177     binderObject->hdr.type = BINDER_TYPE_REMOTE_HANDLE;
178     return FlattenSession(sessionOffset, sessionOfPeer, SUPPORT_TOKENID_VERSION_NUM);
179 }
180 
181 template<class T>
ClearHandleType(flat_binder_object * binderObject)182 void DBinderBaseInvoker<T>::ClearHandleType(flat_binder_object *binderObject)
183 {
184     binderObject->hdr.type = BINDER_TYPE_INVALID_HANDLE;
185     binderObject->cookie = IRemoteObject::IF_PROT_ERROR;
186     binderObject->binder = 0;
187 }
188 
MakeRemoteHandle(std::shared_ptr<T> session)189 template<class T> uint32_t DBinderBaseInvoker<T>::MakeRemoteHandle(std::shared_ptr<T> session)
190 {
191     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
192     if (current == nullptr) {
193         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
194         return 0;
195     }
196 
197     if (!UpdateClientSession(session)) {
198         ZLOGE(LOG_LABEL, "open session failed");
199         return 0;
200     }
201     uint32_t handle = current->GetDBinderIdleHandle(session);
202     if (handle == 0) {
203         ZLOGE(LOG_LABEL, "get dbinder handle failed");
204         if (current->QuerySessionByInfo(session->GetServiceName(), session->GetDeviceId()) == nullptr) {
205             session->CloseDatabusSession();
206         }
207         return 0;
208     }
209     return handle;
210 }
211 
212 template<class T>
TranslateRemoteHandleType(flat_binder_object * binderObject,char * sessionOffset,uint32_t binderVersion)213 bool DBinderBaseInvoker<T>::TranslateRemoteHandleType(flat_binder_object *binderObject, char *sessionOffset,
214     uint32_t binderVersion)
215 {
216     std::shared_ptr<T> sessionOfPeer = nullptr;
217     if (binderObject->cookie == IRemoteObject::IF_PROT_DATABUS ||
218         binderObject->cookie == IRemoteObject::IF_PROT_BINDER) {
219         sessionOfPeer = UnFlattenSession(sessionOffset, binderVersion);
220     }
221     if (sessionOfPeer == nullptr) {
222         ZLOGE(LOG_LABEL, "send a wrong dbinder object");
223         return false;
224     }
225 
226     // 1. If we find matched session, we need to first take its ownership in case of being erased
227     // during proxy initialization
228     // 2. If translate remote handle type concurrently, we may alloc two new handle, and open session
229     // with the same sessionName and deviceId. thus get the same softbus session. this is OK because if
230     // one proxy is reclaimed, we will close session when it is no longer used
231     uint32_t handle = QueryHandleBySession(sessionOfPeer);
232     if (handle == 0) {
233         handle = MakeRemoteHandle(sessionOfPeer);
234         ZLOGI(LOG_LABEL, "create new handle = %{public}u", handle);
235         if (handle == 0) {
236             ZLOGE(LOG_LABEL, "failed to create new handle");
237             return false;
238         }
239     }
240     // If any error occurred before, hdr.type was still BINDER_TYPE_REMOTE_HANDLE
241     // Thus later UnFlattenObject will enter default case and return null
242     binderObject->hdr.type = BINDER_TYPE_HANDLE;
243     binderObject->handle = handle;
244     return true;
245 }
246 
247 /* check data parcel contains object, if yes, get its session as payload of socket packet
248  * if translate any object failed, discard this parcel and do NOT send this parcel to remote
249  */
250 template<class T>
IRemoteObjectTranslateWhenSend(char * dataBuffer,binder_size_t bufferSize,MessageParcel & data,uint32_t socketId,std::shared_ptr<T> sessionObject)251 bool DBinderBaseInvoker<T>::IRemoteObjectTranslateWhenSend(char *dataBuffer, binder_size_t bufferSize,
252     MessageParcel &data, uint32_t socketId, std::shared_ptr<T> sessionObject)
253 {
254     if (data.GetOffsetsSize() <= 0 || dataBuffer == nullptr) {
255         return true;
256     }
257 
258     uint32_t totalSize = 0;
259     binder_size_t *binderObjectsOffsets = reinterpret_cast<binder_size_t *>(data.GetObjectOffsets());
260     uint32_t offsetOfSession = bufferSize + data.GetOffsetsSize() * sizeof(binder_size_t);
261     char *flatOffset = dataBuffer + offsetOfSession;
262 
263     for (size_t i = 0; i < data.GetOffsetsSize(); i++) {
264         auto binderObject = reinterpret_cast<flat_binder_object *>(dataBuffer + *(binderObjectsOffsets + i));
265         switch (binderObject->hdr.type) {
266             case BINDER_TYPE_BINDER: {
267                 uint32_t flatSize = TranslateBinderType(binderObject, flatOffset + totalSize, sessionObject);
268                 if (flatSize == 0) {
269                     ZLOGE(LOG_LABEL, "send an wrong stub object");
270                     return false;
271                 }
272                 totalSize += flatSize;
273                 break;
274             }
275 
276             case BINDER_TYPE_HANDLE: {
277                 uint32_t flatSize = TranslateHandleType(binderObject, flatOffset + totalSize, sessionObject);
278                 if (flatSize == 0) {
279                     ZLOGE(LOG_LABEL, "send an wrong dbinder object");
280                     return false;
281                 }
282                 totalSize += flatSize;
283                 break;
284             }
285 
286             case BINDER_TYPE_FD: {
287                 binderObject->hdr.type = BINDER_TYPE_FDR;
288                 binderObject->handle = -1;
289                 break;
290             }
291 
292             default: {
293                 ZLOGE(LOG_LABEL, "do not support this type of translation");
294                 // do nothing
295                 break;
296             }
297         }
298     }
299     return true;
300 }
301 
302 /* if translate any object failed, should translate next object flush it */
303 template<class T>
IRemoteObjectTranslateWhenRcv(char * dataBuffer,binder_size_t bufferSize,MessageParcel & data,uint32_t socketId,std::shared_ptr<T> sessionObject)304 bool DBinderBaseInvoker<T>::IRemoteObjectTranslateWhenRcv(char *dataBuffer, binder_size_t bufferSize,
305     MessageParcel &data, uint32_t socketId, std::shared_ptr<T> sessionObject)
306 {
307     if (data.GetOffsetsSize() <= 0 || dataBuffer == nullptr) {
308         return true;
309     }
310     binder_size_t *binderObjectsOffsets = reinterpret_cast<binder_size_t *>(data.GetObjectOffsets());
311     uint32_t offsetOfSession = bufferSize + data.GetOffsetsSize() * sizeof(binder_size_t);
312     char *flatOffset = dataBuffer + offsetOfSession;
313 
314     for (size_t i = 0; i < data.GetOffsetsSize(); i++) {
315         auto binderObject = reinterpret_cast<flat_binder_object *>(dataBuffer + *(binderObjectsOffsets + i));
316         switch (binderObject->hdr.type) {
317             case BINDER_TYPE_BINDER: {
318                 ClearBinderType(binderObject);
319                 ZLOGE(LOG_LABEL, "recv an wrong stub object");
320                 break;
321             }
322 
323             case BINDER_TYPE_HANDLE: {
324                 ClearHandleType(binderObject);
325                 ZLOGE(LOG_LABEL, "recv an wrong proxy object");
326                 break;
327             }
328 
329             case BINDER_TYPE_REMOTE_HANDLE: {
330                 if (TranslateRemoteHandleType(binderObject, flatOffset + i * T::GetFlatSessionLen(),
331                     SUPPORT_TOKENID_VERSION_NUM) != true) {
332                     ZLOGE(LOG_LABEL, "recv an wrong dbiner object");
333                     // do nothing, should translate other parcel object, such as fd should set to -1
334                 }
335                 break;
336             }
337             case BINDER_TYPE_FD: {
338                 binderObject->hdr.type = BINDER_TYPE_FDR;
339                 binderObject->handle = -1;
340                 break;
341             }
342             case BINDER_TYPE_FDR: {
343                 if (!TranslateRawData(dataBuffer, data, socketId)) {
344                     ZLOGE(LOG_LABEL, "fail to translate big raw data");
345                     // do nothing
346                 }
347                 break;
348             }
349             default: {
350                 ZLOGE(LOG_LABEL, "do not support this type of translation");
351                 // do nothing
352                 break;
353             }
354         }
355     }
356     return true;
357 }
358 
359 template <class T>
TranslateRawData(char * dataBuffer,MessageParcel & data,uint32_t socketId)360 bool DBinderBaseInvoker<T>::TranslateRawData(char *dataBuffer, MessageParcel &data, uint32_t socketId)
361 {
362     if (data.GetOffsetsSize() <= 0 || socketId == 0) {
363         ZLOGI(LOG_LABEL, "no raw data to translate.");
364         return true;
365     }
366 
367     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
368     if (current == nullptr) {
369         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
370         return false;
371     }
372     std::shared_ptr<InvokerRawData> receivedRawData = current->QueryRawData(socketId);
373     if (receivedRawData == nullptr) {
374         ZLOGE(LOG_LABEL, "cannot found rawData according to the socketId");
375         return false;
376     }
377     std::shared_ptr<char> rawData = receivedRawData->GetData();
378     size_t rawSize = receivedRawData->GetSize();
379     current->DetachRawData(socketId);
380     if (!data.RestoreRawData(rawData, rawSize)) {
381         ZLOGE(LOG_LABEL, "found rawData, but cannot restore them");
382         return false;
383     }
384     return true;
385 }
386 
GetSessionObject(uint32_t handle,uint32_t socketId)387 template <class T> std::shared_ptr<T> DBinderBaseInvoker<T>::GetSessionObject(uint32_t handle, uint32_t socketId)
388 {
389     if (handle != 0) {
390         /* transact case */
391         return QueryServerSessionObject(handle);
392     } else {
393         /* reply case */
394         return QueryClientSessionObject(socketId);
395     }
396 }
397 
GetUniqueSeqNumber(int cmd)398 template <class T> uint64_t DBinderBaseInvoker<T>::GetUniqueSeqNumber(int cmd)
399 {
400     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
401     if (current == nullptr) {
402         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
403         return 0;
404     }
405 
406     if (cmd == BC_TRANSACTION) {
407         return current->GetSeqNumber();
408     } else if (cmd == BC_REPLY) {
409         /* use sender sequence number */
410         return GetSeqNum();
411     } else {
412         return 0;
413     }
414 }
415 
416 template <class T>
ConstructTransData(MessageParcel & data,dbinder_transaction_data & transData,size_t totalSize,uint64_t seqNum,int cmd,__u32 code,__u32 flags)417 void DBinderBaseInvoker<T>::ConstructTransData(MessageParcel &data, dbinder_transaction_data &transData,
418     size_t totalSize, uint64_t seqNum, int cmd, __u32 code, __u32 flags)
419 {
420     transData.sizeOfSelf = totalSize;
421     transData.magic = DBINDER_MAGICWORD;
422     transData.version = SUPPORT_TOKENID_VERSION_NUM;
423     transData.cmd = cmd;
424     transData.code = code;
425     transData.flags = flags;
426     transData.cookie = 0;
427     transData.seqNumber = seqNum;
428     transData.buffer_size = 0;
429     transData.offsets_size = 0;
430     transData.offsets = 0;
431 }
432 
433 template <class T>
ProcessRawData(std::shared_ptr<T> sessionObject,MessageParcel & data,uint64_t seqNum)434 bool DBinderBaseInvoker<T>::ProcessRawData(std::shared_ptr<T> sessionObject, MessageParcel &data, uint64_t seqNum)
435 {
436     if (data.GetRawData() == nullptr || data.GetRawDataSize() == 0) {
437         return true; // do nothing, return true
438     }
439 
440     std::shared_ptr<dbinder_transaction_data> transData = nullptr;
441     size_t totalSize = sizeof(dbinder_transaction_data) + data.GetRawDataSize();
442     transData.reset(reinterpret_cast<dbinder_transaction_data *>(::operator new(totalSize)));
443     if (transData == nullptr) {
444         ZLOGE(LOG_LABEL, "fail to create raw buffer with length = %{public}zu", totalSize);
445         return false;
446     }
447 
448     ConstructTransData(data, *transData, totalSize, seqNum, BC_SEND_RAWDATA, 0, 0);
449     int result = memcpy_s(reinterpret_cast<char *>(transData.get()) + sizeof(dbinder_transaction_data),
450         totalSize - sizeof(dbinder_transaction_data), data.GetRawData(), data.GetRawDataSize());
451     if (result != 0) {
452         ZLOGE(LOG_LABEL, "memcpy data fail size = %{public}zu", data.GetRawDataSize());
453         return false;
454     }
455     result = OnSendRawData(sessionObject, transData.get(), totalSize);
456     if (result != 0) {
457         ZLOGE(LOG_LABEL, "fail to send raw data");
458         return false;
459     }
460     return true;
461 }
462 
463 template <class T>
MoveMessageParcel2TransData(MessageParcel & data,std::shared_ptr<T> sessionObject,std::shared_ptr<dbinder_transaction_data> transData,int32_t socketId,int status)464 bool DBinderBaseInvoker<T>::MoveMessageParcel2TransData(MessageParcel &data, std::shared_ptr<T> sessionObject,
465     std::shared_ptr<dbinder_transaction_data> transData, int32_t socketId, int status)
466 {
467     if (data.GetDataSize() > 0) {
468         /* Send this parcel's data through the socket. */
469         transData->buffer_size = data.GetDataSize();
470         uint32_t useSize = transData->sizeOfSelf - sizeof(dbinder_transaction_data);
471         int memcpyResult =
472             memcpy_s(transData->buffer, useSize, reinterpret_cast<void *>(data.GetData()), transData->buffer_size);
473         if (data.GetOffsetsSize() > 0) {
474             memcpyResult += memcpy_s(transData->buffer + transData->buffer_size, useSize - transData->buffer_size,
475                 reinterpret_cast<void *>(data.GetObjectOffsets()), data.GetOffsetsSize() * sizeof(binder_size_t));
476         }
477         if (memcpyResult != 0) {
478             ZLOGE(LOG_LABEL, "parcel data memcpy_s failed");
479             return false;
480         }
481         transData->offsets_size = data.GetOffsetsSize() * sizeof(binder_size_t);
482         transData->offsets = transData->buffer_size;
483 
484         if (!CheckTransactionData(transData.get())) {
485             ZLOGE(LOG_LABEL, "check trans data fail");
486             return false;
487         }
488         if (!IRemoteObjectTranslateWhenSend(reinterpret_cast<char *>(transData->buffer), transData->buffer_size,
489             data, socketId, sessionObject)) {
490             ZLOGE(LOG_LABEL, "translate object failed");
491             return false;
492         }
493     } else {
494         transData->flags |= TF_STATUS_CODE;
495         transData->buffer_size = sizeof(binder_size_t);
496         transData->offsets_size = static_cast<binder_size_t>(status);
497         transData->offsets = transData->buffer_size;
498     }
499     return true;
500 }
501 
502 template <class T>
ProcessNormalData(std::shared_ptr<T> sessionObject,MessageParcel & data,int32_t handle,int32_t socketId,uint64_t seqNum,int cmd,__u32 code,__u32 flags,int status)503 std::shared_ptr<dbinder_transaction_data> DBinderBaseInvoker<T>::ProcessNormalData(std::shared_ptr<T> sessionObject,
504     MessageParcel &data, int32_t handle, int32_t socketId, uint64_t seqNum, int cmd, __u32 code, __u32 flags,
505     int status)
506 {
507     uint32_t sendSize = ((data.GetDataSize() > 0) ? data.GetDataSize() : sizeof(binder_size_t)) +
508         sizeof(struct dbinder_transaction_data) + data.GetOffsetsSize() * T::GetFlatSessionLen() +
509         data.GetOffsetsSize() * sizeof(binder_size_t);
510 
511     std::shared_ptr<dbinder_transaction_data> transData = nullptr;
512     transData.reset(reinterpret_cast<dbinder_transaction_data *>(::operator new(sendSize)));
513     if (transData == nullptr) {
514         ZLOGE(LOG_LABEL, "new buffer failed of length = %{public}u", sendSize);
515         return nullptr;
516     }
517     ConstructTransData(data, *transData, sendSize, seqNum, cmd, code, flags);
518     transData->cookie = (handle == 0) ? 0 : sessionObject->GetStubIndex();
519     if (MoveMessageParcel2TransData(data, sessionObject, transData, socketId, status) != true) {
520         ZLOGE(LOG_LABEL, "move parcel to transData failed, handle = %{public}d", handle);
521         return nullptr;
522     }
523     return transData;
524 }
525 
526 template <class T>
MoveTransData2Buffer(std::shared_ptr<T> sessionObject,std::shared_ptr<dbinder_transaction_data> transData)527 bool DBinderBaseInvoker<T>::MoveTransData2Buffer(std::shared_ptr<T> sessionObject,
528     std::shared_ptr<dbinder_transaction_data> transData)
529 {
530     std::shared_ptr<BufferObject> sessionBuff = sessionObject->GetSessionBuff();
531     if (sessionBuff == nullptr) {
532         ZLOGE(LOG_LABEL, "get session buffer fail");
533         return false;
534     }
535 
536     uint32_t sendSize = transData->sizeOfSelf;
537     char *sendBuffer = sessionBuff->GetSendBufferAndLock(sendSize);
538     /* session buffer contain mutex, need release mutex */
539     if (sendBuffer == nullptr) {
540         ZLOGE(LOG_LABEL, "buffer alloc failed in session");
541         return false;
542     }
543 
544     sessionBuff->UpdateSendBuffer(sendSize);
545     ssize_t writeCursor = sessionBuff->GetSendBufferWriteCursor();
546     ssize_t readCursor = sessionBuff->GetSendBufferReadCursor();
547     if (writeCursor < 0 || readCursor < 0 || sendSize > sessionBuff->GetSendBufferSize() - writeCursor) {
548         sessionBuff->ReleaseSendBufferLock();
549         ZLOGE(LOG_LABEL, "sender's data is large than idle buffer, writecursor: %{public}zd, readcursor: %{public}zd,\
550             sendSize: %{public}u, bufferSize: %{public}u",
551             writeCursor, readCursor, sendSize, sessionBuff->GetSendBufferSize());
552         return false;
553     }
554     if (memcpy_s(sendBuffer + writeCursor, sendSize, transData.get(), sendSize)) {
555         sessionBuff->ReleaseSendBufferLock();
556         ZLOGE(LOG_LABEL, "fail to copy from tr to sendBuffer, parcelSize = %{public}u", sendSize);
557         return false;
558     }
559 
560     writeCursor += static_cast<ssize_t>(sendSize);
561     sessionBuff->SetSendBufferWriteCursor(writeCursor);
562     sessionBuff->SetSendBufferReadCursor(readCursor);
563     sessionBuff->ReleaseSendBufferLock();
564     return true;
565 }
566 
567 template <class T>
WriteTransaction(int cmd,uint32_t flags,int32_t handle,int32_t socketId,uint32_t code,MessageParcel & data,uint64_t & seqNumber,int status)568 std::shared_ptr<T> DBinderBaseInvoker<T>::WriteTransaction(int cmd, uint32_t flags, int32_t handle, int32_t socketId,
569     uint32_t code, MessageParcel &data, uint64_t &seqNumber, int status)
570 {
571     std::shared_ptr<T> sessionObject = GetSessionObject(handle, socketId);
572     if (sessionObject == nullptr) {
573         ZLOGE(LOG_LABEL, "session is not exist for listenFd = %d, handle = %d", socketId, handle);
574         return nullptr;
575     }
576 
577     uint64_t seqNum = GetUniqueSeqNumber(cmd);
578     if (seqNum == 0) {
579         ZLOGE(LOG_LABEL, "seqNum invalid");
580         return nullptr;
581     }
582     /* save seqNum for wait thread */
583     seqNumber = seqNum;
584     /* if MessageParcel has raw data, send raw data first, then send MessageParcel to peer */
585     if (ProcessRawData(sessionObject, data, seqNum) != true) {
586         ZLOGE(LOG_LABEL, "send rawdata failed");
587         return nullptr;
588     }
589     std::shared_ptr<dbinder_transaction_data> transData =
590         ProcessNormalData(sessionObject, data, handle, socketId, seqNum, cmd, code, flags, status);
591     if (transData == nullptr) {
592         ZLOGE(LOG_LABEL, "send normal data failed");
593         return nullptr;
594     }
595 
596     if (MoveTransData2Buffer(sessionObject, transData) != true) {
597         ZLOGE(LOG_LABEL, "move transaction data to buffer failed");
598         return nullptr;
599     }
600     return sessionObject;
601 }
602 
603 template <class T>
HandleReply(uint64_t seqNumber,MessageParcel * reply,std::shared_ptr<ThreadMessageInfo> messageInfo)604 int DBinderBaseInvoker<T>::HandleReply(uint64_t seqNumber, MessageParcel *reply,
605     std::shared_ptr<ThreadMessageInfo> messageInfo)
606 {
607     if (reply == nullptr) {
608         ZLOGE(LOG_LABEL, "no need reply, free the buffer");
609         return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
610     }
611 
612     if (messageInfo == nullptr) {
613         ZLOGE(LOG_LABEL, "receive buffer is nullptr");
614 #ifndef BUILD_PUBLIC_VERSION
615         ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, std::string(DbinderErrorCode::ERROR_TYPE),
616             DbinderErrorCode::RPC_DRIVER, std::string(DbinderErrorCode::ERROR_CODE),
617             DbinderErrorCode::HANDLE_RECV_DATA_FAILURE);
618 #endif
619         return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
620     }
621 
622     if (messageInfo->flags & MessageOption::TF_STATUS_CODE) {
623         int32_t err = static_cast<int32_t>(messageInfo->offsetsSize);
624         return err;
625     }
626     if (messageInfo->buffer == nullptr) {
627         ZLOGE(LOG_LABEL, "need reply message, but buffer is nullptr");
628         return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
629     }
630     auto allocator = new (std::nothrow) DBinderRecvAllocator();
631     if (allocator == nullptr) {
632         ZLOGE(LOG_LABEL, "create DBinderRecvAllocator object failed");
633         return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
634     }
635     if (!reply->SetAllocator(allocator)) {
636         ZLOGE(LOG_LABEL, "SetAllocator failed");
637         delete allocator;
638         return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
639     }
640     reply->ParseFrom(reinterpret_cast<uintptr_t>(messageInfo->buffer), messageInfo->bufferSize);
641 
642     if (messageInfo->offsetsSize > 0) {
643         reply->InjectOffsets(
644             reinterpret_cast<binder_uintptr_t>(reinterpret_cast<char *>(messageInfo->buffer) + messageInfo->offsets),
645             messageInfo->offsetsSize / sizeof(binder_size_t));
646     }
647 
648     if (!IRemoteObjectTranslateWhenRcv(reinterpret_cast<char *>(messageInfo->buffer), messageInfo->bufferSize, *reply,
649         messageInfo->socketId, nullptr)) {
650         ZLOGE(LOG_LABEL, "translate object failed");
651         return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
652     }
653 
654     return ERR_NONE;
655 }
656 
Dealloc(void * data)657 template <class T> void DBinderBaseInvoker<T>::DBinderSendAllocator::Dealloc(void *data) {}
658 
Dealloc(void * data)659 template <class T> void DBinderBaseInvoker<T>::DBinderRecvAllocator::Dealloc(void *data)
660 {
661     delete[](unsigned char *) data;
662 }
663 
664 template <class T>
WaitForReply(uint64_t seqNumber,MessageParcel * reply,uint32_t handle,int userWaitTime)665 int DBinderBaseInvoker<T>::WaitForReply(uint64_t seqNumber, MessageParcel *reply, uint32_t handle, int userWaitTime)
666 {
667     /* if reply == nullptr, this is a one way message */
668     if (reply == nullptr) {
669         return NO_ERROR;
670     }
671 
672     std::shared_ptr<ThreadMessageInfo> messageInfo = MakeThreadMessageInfo(handle);
673     if (messageInfo == nullptr) {
674         ZLOGE(LOG_LABEL, "make thread message info failed, no memory");
675         return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
676     }
677 
678     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
679     if (current == nullptr) {
680         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
681         return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
682     }
683     /* wait for reply */
684     if (!current->AddSendThreadInWait(seqNumber, messageInfo, userWaitTime)) {
685         current->EraseThreadBySeqNumber(seqNumber);
686         ZLOGE(LOG_LABEL, "sender thread wait reply message time out");
687         return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
688     }
689 
690     int32_t err = HandleReply(seqNumber, reply, messageInfo);
691     current->EraseThreadBySeqNumber(seqNumber);
692     messageInfo->buffer = nullptr;
693     messageInfo->ready = false;
694     return err;
695 }
696 
697 template <class T>
SendOrWaitForCompletion(int userWaitTime,uint64_t seqNumber,std::shared_ptr<T> sessionOfPeer,MessageParcel * reply)698 int DBinderBaseInvoker<T>::SendOrWaitForCompletion(int userWaitTime, uint64_t seqNumber,
699     std::shared_ptr<T> sessionOfPeer, MessageParcel *reply)
700 {
701     if (seqNumber == 0) {
702         ZLOGE(LOG_LABEL, "seqNumber can not be zero");
703         return RPC_BASE_INVOKER_INVALID_DATA_ERR;
704     }
705     if (sessionOfPeer == nullptr) {
706         ZLOGE(LOG_LABEL, "current session is invalid");
707         return RPC_BASE_INVOKER_INVALID_DATA_ERR;
708     }
709     int result = OnSendMessage(sessionOfPeer);
710     if (result != 0) {
711         ZLOGE(LOG_LABEL, "fail to send to remote session with error = %{public}d", result);
712         return RPC_BASE_INVOKER_INVALID_DATA_ERR;
713     }
714     result = WaitForReply(seqNumber, reply, sessionOfPeer->GetSessionHandle(), userWaitTime);
715     if (result != ERR_NONE) {
716         ZLOGE(LOG_LABEL, "dbinder wait for reply error: %{public}d", result);
717     }
718     return result;
719 }
720 
721 template <class T>
SendRequest(int32_t handle,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)722 int DBinderBaseInvoker<T>::SendRequest(int32_t handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
723     MessageOption &option)
724 {
725     uint64_t seqNumber = 0;
726     int ret;
727 
728     uint32_t flags = static_cast<uint32_t>(option.GetFlags());
729     int userWaitTime = option.GetWaitTime();
730     MessageParcel &newData = const_cast<MessageParcel &>(data);
731     size_t oldWritePosition = newData.GetWritePosition();
732     HiTraceId traceId = HiTraceChain::GetId();
733     // set client send trace point if trace is enabled
734     HiTraceId childId = HitraceInvoker::TraceClientSend(handle, code, newData, flags, traceId);
735     std::shared_ptr<T> session = WriteTransaction(BC_TRANSACTION, flags, handle, 0, code, data, seqNumber, 0);
736     if (session == nullptr) {
737         newData.RewindWrite(oldWritePosition);
738         ZLOGE(LOG_LABEL, "seqNumber can not be zero,handle=%d", handle);
739 #ifndef BUILD_PUBLIC_VERSION
740         ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, std::string(DbinderErrorCode::ERROR_TYPE),
741             DbinderErrorCode::RPC_DRIVER, std::string(DbinderErrorCode::ERROR_CODE),
742             DbinderErrorCode::TRANSACT_DATA_FAILURE);
743 #endif
744         return RPC_BASE_INVOKER_WRITE_TRANS_ERR;
745     }
746 
747     if (flags & TF_ONE_WAY) {
748         ret = SendOrWaitForCompletion(userWaitTime, seqNumber, session, nullptr);
749     } else {
750         ret = SendOrWaitForCompletion(userWaitTime, seqNumber, session, &reply);
751     }
752     HitraceInvoker::TraceClientReceieve(handle, code, flags, traceId, childId);
753     // restore Parcel data
754     newData.RewindWrite(oldWritePosition);
755     return ret;
756 }
757 
AddDeathRecipient(int32_t handle,void * cookie)758 template <class T> bool DBinderBaseInvoker<T>::AddDeathRecipient(int32_t handle, void *cookie)
759 {
760     return true;
761 }
762 
RemoveDeathRecipient(int32_t handle,void * cookie)763 template <class T> bool DBinderBaseInvoker<T>::RemoveDeathRecipient(int32_t handle, void *cookie)
764 {
765     return true;
766 }
767 
SetMaxWorkThread(int maxThreadNum)768 template <class T> bool DBinderBaseInvoker<T>::SetMaxWorkThread(int maxThreadNum)
769 {
770     return true;
771 }
772 
SendReply(MessageParcel & reply,uint32_t flags,int32_t result)773 template <class T> int DBinderBaseInvoker<T>::SendReply(MessageParcel &reply, uint32_t flags, int32_t result)
774 {
775     uint64_t seqNumber = 0;
776     std::shared_ptr<T> sessionObject = WriteTransaction(BC_REPLY, flags, 0,
777         GetClientFd(), 0, reply, seqNumber, result);
778 
779     if (seqNumber == 0) {
780         ZLOGE(LOG_LABEL, "seqNumber can not be zero");
781         return RPC_BASE_INVOKER_SEND_REPLY_ERR;
782     }
783     SendOrWaitForCompletion(0, seqNumber, sessionObject, nullptr);
784     return 0;
785 }
786 
MakeThreadMessageInfo(uint32_t handle)787 template <class T> std::shared_ptr<ThreadMessageInfo> DBinderBaseInvoker<T>::MakeThreadMessageInfo(uint32_t handle)
788 {
789     std::shared_ptr<ThreadMessageInfo> messageInfo = std::make_shared<struct ThreadMessageInfo>();
790     if (messageInfo == nullptr) {
791         ZLOGE(LOG_LABEL, "no memory");
792         return nullptr;
793     }
794 
795     messageInfo->buffer = nullptr;
796     messageInfo->offsets = 0;
797     messageInfo->socketId = handle;
798     messageInfo->ready = false;
799     return messageInfo;
800 }
801 
802 template <class T>
MakeThreadProcessInfo(uint32_t handle,const char * inBuffer,uint32_t size)803 std::shared_ptr<ThreadProcessInfo> DBinderBaseInvoker<T>::MakeThreadProcessInfo(uint32_t handle, const char *inBuffer,
804     uint32_t size)
805 {
806     if (inBuffer == nullptr || size < sizeof(dbinder_transaction_data) || size > SOCKET_MAX_BUFF_SIZE) {
807         ZLOGE(LOG_LABEL, "buffer is null or size invalid");
808         return nullptr;
809     }
810 
811     std::shared_ptr<ThreadProcessInfo> processInfo = std::make_shared<ThreadProcessInfo>();
812     if (processInfo == nullptr) {
813         ZLOGE(LOG_LABEL, "make_shared processInfo fail");
814         return nullptr;
815     }
816     std::shared_ptr<char> buffer(new (std::nothrow) char[size]);
817     if (buffer == nullptr) {
818         ZLOGE(LOG_LABEL, "new buffer failed of length = %{public}u", size);
819         return nullptr;
820     }
821 
822     int memcpyResult = memcpy_s(buffer.get(), size, inBuffer, size);
823     if (memcpyResult != 0) {
824         ZLOGE(LOG_LABEL, "memcpy_s failed , size = %{public}u", size);
825         return nullptr;
826     }
827 
828     processInfo->listenFd = handle;
829     processInfo->packageSize = size;
830     processInfo->buffer = buffer;
831     return processInfo;
832 }
833 
StartProcessLoop(uint32_t handle,const char * buffer,uint32_t size)834 template <class T> void DBinderBaseInvoker<T>::StartProcessLoop(uint32_t handle, const char *buffer, uint32_t size)
835 {
836     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
837     if (current == nullptr) {
838         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
839         return;
840     }
841     std::shared_ptr<ThreadProcessInfo> processInfo = MakeThreadProcessInfo(handle, buffer, size);
842     if (processInfo == nullptr) {
843         ZLOGE(LOG_LABEL, "processInfo is nullptr");
844         return;
845     }
846     std::thread::id threadId = current->GetIdleDataThread();
847     if (threadId == std::thread::id()) {
848         bool result = CreateProcessThread();
849         if (!result) {
850             int socketThreadNum = current->GetSocketTotalThreadNum();
851             ZLOGE(LOG_LABEL,
852                 "create IO thread failed, current socket thread num=%d", socketThreadNum);
853             /* thread create too much, wait some thread be idle */
854         }
855         do {
856             /*  no IO thread in idle state, wait a monent */
857             std::this_thread::sleep_for(std::chrono::milliseconds(1));
858         } while ((threadId = current->GetIdleDataThread()) == std::thread::id());
859     }
860 
861     current->AddDataInfoToThread(threadId, processInfo);
862     current->WakeUpDataThread(threadId);
863     return;
864 }
865 
ProcessTransaction(dbinder_transaction_data * tr,uint32_t listenFd)866 template <class T> void DBinderBaseInvoker<T>::ProcessTransaction(dbinder_transaction_data *tr, uint32_t listenFd)
867 {
868     MessageParcel data, reply;
869 
870     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
871     if (current == nullptr) {
872         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
873         return;
874     }
875 
876     auto allocator = new (std::nothrow) DBinderSendAllocator();
877     if (allocator == nullptr) {
878         ZLOGE(LOG_LABEL, "DBinderSendAllocator Creation failed");
879         return;
880     }
881     if (!data.SetAllocator(allocator)) {
882         ZLOGE(LOG_LABEL, "SetAllocator failed");
883         delete allocator;
884         return;
885     }
886     data.ParseFrom(reinterpret_cast<uintptr_t>(tr->buffer), tr->buffer_size);
887     if (!(tr->flags & MessageOption::TF_STATUS_CODE) && tr->offsets_size > 0) {
888         data.InjectOffsets(reinterpret_cast<binder_uintptr_t>(reinterpret_cast<char *>(tr->buffer) + tr->offsets),
889             tr->offsets_size / sizeof(binder_size_t));
890     }
891     uint32_t &newflags = const_cast<uint32_t &>(tr->flags);
892     int isServerTraced = HitraceInvoker::TraceServerReceieve(tr->cookie, tr->code, data, newflags);
893 
894     const pid_t oldPid = GetCallerPid();
895     const auto oldUid = static_cast<const uid_t>(GetCallerUid());
896     const std::string oldDeviceId = GetCallerDeviceID();
897     uint32_t oldStatus = GetStatus();
898     uint32_t oldClientFd = GetClientFd();
899     const uint32_t oldTokenId = GetCallerTokenID();
900     if (CheckAndSetCallerInfo(listenFd, tr->cookie) != ERR_NONE) {
901         ZLOGE(LOG_LABEL, "check and set caller info failed, cmd: %{public}u", tr->code);
902         return;
903     }
904     SetStatus(IRemoteInvoker::ACTIVE_INVOKER);
905 
906     const uint32_t flags = tr->flags;
907     uint64_t senderSeqNumber = tr->seqNumber;
908     int error = ERR_NONE;
909     {
910         std::lock_guard<std::mutex> lockGuard(objectMutex_);
911         auto *stub = current->QueryStubByIndex(tr->cookie);
912         if (stub == nullptr) {
913             ZLOGE(LOG_LABEL, "stubIndex is invalid");
914             return;
915         }
916         if (!IRemoteObjectTranslateWhenRcv(reinterpret_cast<char *>(tr->buffer), tr->buffer_size, data,
917             listenFd, nullptr)) {
918             ZLOGE(LOG_LABEL, "translate object failed");
919             return;
920         }
921 
922         auto *stubObject = reinterpret_cast<IPCObjectStub *>(stub);
923         MessageOption option;
924         option.SetFlags(flags);
925         // cannot use stub any more after SendRequest because this cmd may be
926         // dbinder dec ref and thus stub will be destroyed
927         int error = stubObject->SendRequest(tr->code, data, reply, option);
928         if (error != ERR_NONE) {
929             ZLOGE(LOG_LABEL, "stub sendrequest failed, cmd: %{public}u, error: %{public}d", tr->code, error);
930             // can not return;
931         }
932     }
933 
934     if (data.GetRawData() != nullptr) {
935         ZLOGE(LOG_LABEL, "delete raw data in process skeleton, fd: %{public}u", listenFd);
936         current->DetachRawData(listenFd);
937     }
938     HitraceInvoker::TraceServerSend(tr->cookie, tr->code, isServerTraced, newflags);
939     if (!(flags & MessageOption::TF_ASYNC)) {
940         SetSeqNum(senderSeqNumber);
941         SendReply(reply, 0, error);
942         SetSeqNum(0);
943     }
944 
945     SetCallerPid(oldPid);
946     SetCallerUid(oldUid);
947     SetCallerDeviceID(oldDeviceId);
948     SetStatus(oldStatus);
949     SetClientFd(oldClientFd);
950     SetCallerTokenID(oldTokenId);
951 }
952 
ProcessReply(dbinder_transaction_data * tr,uint32_t listenFd)953 template <class T> void DBinderBaseInvoker<T>::ProcessReply(dbinder_transaction_data *tr, uint32_t listenFd)
954 {
955     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
956     if (current == nullptr) {
957         ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr, can not wakeup thread");
958         return;
959     }
960 
961     std::shared_ptr<ThreadMessageInfo> messageInfo = current->QueryThreadBySeqNumber(tr->seqNumber);
962     if (messageInfo == nullptr) {
963         ZLOGE(LOG_LABEL, "no thread waiting reply message of this seqNumber: %{public}llu", tr->seqNumber);
964         /* messageInfo is null, no thread need to wakeup */
965         return;
966     }
967 
968     /* tr->sizeOfSelf > sizeof(dbinder_transaction_data) is checked in CheckTransactionData */
969     messageInfo->buffer = new (std::nothrow) unsigned char[tr->sizeOfSelf - sizeof(dbinder_transaction_data)];
970     if (messageInfo->buffer == nullptr) {
971         ZLOGE(LOG_LABEL, "some thread is waiting for reply message, but no memory");
972         /* wake up sender thread */
973         current->WakeUpThreadBySeqNumber(tr->seqNumber, listenFd);
974         return;
975     }
976     /* copy receive message to sender thread */
977     int memcpyResult = memcpy_s(messageInfo->buffer, tr->sizeOfSelf - sizeof(dbinder_transaction_data), tr->buffer,
978         tr->sizeOfSelf - sizeof(dbinder_transaction_data));
979     if (memcpyResult != 0) {
980         ZLOGE(LOG_LABEL, "memcpy_s failed");
981         delete[](unsigned char *) messageInfo->buffer;
982         messageInfo->buffer = nullptr;
983         /* wake up sender thread even no memssage */
984         current->WakeUpThreadBySeqNumber(tr->seqNumber, listenFd);
985         return;
986     }
987 
988     messageInfo->flags = tr->flags;
989     messageInfo->bufferSize = tr->buffer_size;
990     messageInfo->offsetsSize = tr->offsets_size;
991     messageInfo->offsets = tr->offsets;
992     messageInfo->socketId = listenFd;
993 
994     /* wake up sender thread */
995     current->WakeUpThreadBySeqNumber(tr->seqNumber, listenFd);
996 }
997 
OnTransaction(std::shared_ptr<ThreadProcessInfo> processInfo)998 template <class T> void DBinderBaseInvoker<T>::OnTransaction(std::shared_ptr<ThreadProcessInfo> processInfo)
999 {
1000     if (processInfo == nullptr) {
1001         ZLOGE(LOG_LABEL, "processInfo is error!");
1002         return;
1003     }
1004     uint32_t listenFd = processInfo->listenFd;
1005     char *package = processInfo->buffer.get();
1006 
1007     if (package == nullptr || listenFd == 0) {
1008         ZLOGE(LOG_LABEL, "package is null or listenFd invalid!");
1009         return;
1010     }
1011 
1012     dbinder_transaction_data *tr = reinterpret_cast<dbinder_transaction_data *>(package);
1013     if (tr->sizeOfSelf < sizeof(dbinder_transaction_data)) {
1014         ZLOGE(LOG_LABEL, "package is invalid");
1015         return;
1016     }
1017 
1018     if (tr->cmd == BC_TRANSACTION) {
1019         ProcessTransaction(tr, listenFd);
1020     } else if (tr->cmd == BC_REPLY) {
1021         ProcessReply(tr, listenFd);
1022     }
1023     return;
1024 }
1025 
PingService(int32_t handle)1026 template <class T> bool DBinderBaseInvoker<T>::PingService(int32_t handle)
1027 {
1028     return true;
1029 }
1030 
GetSAMgrObject()1031 template <class T> sptr<IRemoteObject> DBinderBaseInvoker<T>::GetSAMgrObject()
1032 {
1033     return nullptr;
1034 }
1035 
1036 
SetRegistryObject(sptr<IRemoteObject> & object)1037 template <class T> bool DBinderBaseInvoker<T>::SetRegistryObject(sptr<IRemoteObject> &object)
1038 {
1039     return true;
1040 }
1041 
FreeBuffer(void * data)1042 template <class T> void DBinderBaseInvoker<T>::FreeBuffer(void *data)
1043 {
1044     return;
1045 }
1046 
CheckTransactionData(const dbinder_transaction_data * tr)1047 template <class T> bool DBinderBaseInvoker<T>::CheckTransactionData(const dbinder_transaction_data *tr) const
1048 {
1049     if (tr->sizeOfSelf == 0 || tr->sizeOfSelf > SOCKET_MAX_BUFF_SIZE || tr->buffer_size > SOCKET_MAX_BUFF_SIZE ||
1050         tr->buffer_size == 0 || tr->offsets != tr->buffer_size ||
1051         tr->sizeOfSelf < sizeof(dbinder_transaction_data) + tr->buffer_size) {
1052         return false;
1053     }
1054     if ((tr->flags & MessageOption::TF_STATUS_CODE) && (tr->offsets != sizeof(binder_size_t))) {
1055         return false;
1056     }
1057     if (!(tr->flags & MessageOption::TF_STATUS_CODE)) {
1058         if (tr->offsets_size > (tr->sizeOfSelf - sizeof(dbinder_transaction_data) - tr->buffer_size)) {
1059             return false;
1060         }
1061         binder_size_t sessionSize =
1062             tr->sizeOfSelf - tr->buffer_size - sizeof(dbinder_transaction_data) - tr->offsets_size;
1063         if (sessionSize * sizeof(binder_size_t) != tr->offsets_size * T::GetFlatSessionLen()) {
1064             return false;
1065         }
1066     }
1067 
1068     return true;
1069 }
1070 
GetObjectMutex()1071 template <class T> std::mutex &DBinderBaseInvoker<T>::GetObjectMutex()
1072 {
1073     return objectMutex_;
1074 }
1075 
1076 } // namespace OHOS
1077 #endif // OHOS_IPC_DBINDER_BASE_INVOKER_H
1078