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