1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dbinder_service.h"
17 
18 #include <stdbool.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/time.h>
22 
23 #include "dbinder_ipc_adapter.h"
24 #include "dbinder_service_inner.h"
25 #include "dbinder_stub.h"
26 #include "dbinder_trans_callback.h"
27 #include "ipc_skeleton.h"
28 #include "ipc_proxy_inner.h"
29 #include "rpc_errno.h"
30 #include "rpc_log.h"
31 #include "rpc_session_handle.h"
32 #include "rpc_trans.h"
33 #include "rpc_types.h"
34 #include "securec.h"
35 #include "serializer.h"
36 #include "utils_list.h"
37 
38 typedef struct {
39     UTILS_DL_LIST list;
40     char *serviceName;
41     uintptr_t binder;
42 } RemoteBinderObjects;
43 
44 typedef struct {
45     UTILS_DL_LIST remoteBinderObjects;
46     pthread_mutex_t mutex;
47 } RemoteBinderObjectsList;
48 
49 typedef struct {
50     UTILS_DL_LIST dBinderStubs;
51     pthread_mutex_t mutex;
52 } DBinderStubRegistedList;
53 
54 typedef struct {
55     UTILS_DL_LIST list;
56     pthread_mutex_t mutex;
57     pthread_cond_t condition;
58     uint32_t seqNumber;
59 } ThreadLockInfo;
60 
61 typedef struct {
62     UTILS_DL_LIST threadLocks;
63     pthread_mutex_t mutex;
64 } ThreadLockInfoList;
65 
66 typedef struct {
67     UTILS_DL_LIST sessionInfos;
68     pthread_mutex_t mutex;
69 } SessionInfoList;
70 
71 typedef struct {
72     UTILS_DL_LIST proxyObject;
73     pthread_mutex_t mutex;
74 } ProxyObjectList;
75 
76 static RemoteBinderObjectsList g_binderList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
77 static DBinderStubRegistedList g_stubRegistedList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
78 static ThreadLockInfoList g_threadLockInfoList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
79 static SessionInfoList g_sessionInfoList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
80 static ProxyObjectList g_proxyObjectList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
81 static SessionIdList g_sessionIdList = {
82     .mutex = PTHREAD_MUTEX_INITIALIZER,
83     .condition = PTHREAD_COND_INITIALIZER
84 };
85 
86 static TransInterface *g_trans = NULL;
87 static char const *DBINDER_SESSION_NAME = "DBinderService";
88 static const uint32_t RETRY_TIMES = 2;
89 static const int32_t FIRST_SYS_ABILITY_ID = 0x00000001;
90 static const int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
91 static int g_listInit = 0;
92 
InitDBinder(void)93 static int32_t InitDBinder(void)
94 {
95     if (g_listInit == 0) {
96         UtilsListInit(&g_binderList.remoteBinderObjects);
97         UtilsListInit(&g_stubRegistedList.dBinderStubs);
98         UtilsListInit(&g_threadLockInfoList.threadLocks);
99         UtilsListInit(&g_sessionInfoList.sessionInfos);
100         UtilsListInit(&g_proxyObjectList.proxyObject);
101         UtilsListInit(&g_sessionIdList.idList);
102         g_listInit = 1;
103     }
104     return ERR_NONE;
105 }
106 
GetRegisterService(uintptr_t binderObject)107 static char *GetRegisterService(uintptr_t binderObject)
108 {
109     RemoteBinderObjects *node = NULL;
110     pthread_mutex_lock(&g_binderList.mutex);
111     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_binderList.remoteBinderObjects, RemoteBinderObjects, list)
112     {
113         if (node->binder == binderObject) {
114             pthread_mutex_unlock(&g_binderList.mutex);
115             return node->serviceName;
116         }
117     }
118     pthread_mutex_unlock(&g_binderList.mutex);
119     return NULL;
120 }
121 
AddRegisterService(RemoteBinderObjects * binderObject)122 static void AddRegisterService(RemoteBinderObjects *binderObject)
123 {
124     pthread_mutex_lock(&g_binderList.mutex);
125     UtilsListAdd(&g_binderList.remoteBinderObjects, &binderObject->list);
126     pthread_mutex_unlock(&g_binderList.mutex);
127 }
128 
CheckBinderParams(const void * serviceName,uint32_t nameLen,const char * deviceID,uint32_t idLen,void * remoteObject)129 static int32_t CheckBinderParams(const void *serviceName, uint32_t nameLen, const char *deviceID,
130     uint32_t idLen, void *remoteObject)
131 {
132     if (serviceName == NULL || deviceID == NULL || remoteObject == NULL) {
133         RPC_LOG_ERROR("MakeRemoteBinder null poiter");
134         return ERR_FAILED;
135     }
136 
137     if (strlen((char *)serviceName) != nameLen || strlen(deviceID) != idLen) {
138         RPC_LOG_ERROR("MakeRemoteBinder length invalid");
139         return ERR_FAILED;
140     }
141     return ERR_NONE;
142 }
143 
QueryDBinderStub(const char * serviceName,const char * deviceID,uintptr_t binderObject)144 static DBinderServiceStub *QueryDBinderStub(const char *serviceName, const char *deviceID,
145     uintptr_t binderObject)
146 {
147     pthread_mutex_lock(&g_stubRegistedList.mutex);
148     DBinderServiceStub *node = NULL;
149     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_stubRegistedList.dBinderStubs, DBinderServiceStub, list)
150     {
151         if (IsSameStub(node, serviceName, deviceID, binderObject)) {
152             RPC_LOG_INFO("find dBinderStub in g_stubRegistedList");
153             pthread_mutex_unlock(&g_stubRegistedList.mutex);
154             return node;
155         }
156     }
157     pthread_mutex_unlock(&g_stubRegistedList.mutex);
158     return NULL;
159 }
160 
AddDBinderStub(DBinderServiceStub * stub)161 static void AddDBinderStub(DBinderServiceStub *stub)
162 {
163     pthread_mutex_lock(&g_stubRegistedList.mutex);
164     UtilsListAdd(&g_stubRegistedList.dBinderStubs, &stub->list);
165     pthread_mutex_unlock(&g_stubRegistedList.mutex);
166 }
167 
FindOrNewDBinderStub(const char * serviceName,uint32_t nameLen,const char * deviceID,uint32_t idLen,uintptr_t binderObject)168 static DBinderServiceStub *FindOrNewDBinderStub(const char *serviceName, uint32_t nameLen,
169     const char *deviceID, uint32_t idLen, uintptr_t binderObject)
170 {
171     if (serviceName == NULL || deviceID == NULL) {
172         RPC_LOG_ERROR("FindOrNewDBinderStub get null input params");
173         return NULL;
174     }
175 
176     DBinderServiceStub *node = QueryDBinderStub(serviceName, deviceID, binderObject);
177     if (node != NULL) {
178         RPC_LOG_INFO("DBinderStub cached already");
179         return node;
180     }
181 
182     node = (DBinderServiceStub *)malloc(sizeof(DBinderServiceStub));
183     if (node == NULL) {
184         RPC_LOG_ERROR("dBinderServiceStub malloc failed");
185         return NULL;
186     }
187     if (GetDBinderStub(serviceName, deviceID, binderObject, node) != ERR_NONE)  {
188         RPC_LOG_ERROR("GetDBinderStub failed");
189         free(node);
190         return NULL;
191     }
192 
193     AddDBinderStub(node);
194     return node;
195 }
196 
SendDataToRemote(const char * deviceId,const DHandleEntryTxRx * msg)197 static int32_t SendDataToRemote(const char *deviceId, const DHandleEntryTxRx *msg)
198 {
199     if (deviceId == NULL || msg == NULL) {
200         return ERR_FAILED;
201     }
202 
203     int32_t sessionId = g_trans->Connect(DBINDER_SESSION_NAME, deviceId, NULL);
204     if (sessionId < 0) {
205         RPC_LOG_ERROR("SendDataToRemote connect failed");
206         return ERR_FAILED;
207     }
208 
209     if (WaitForSessionIdReady(&g_sessionIdList, sessionId) != ERR_NONE) {
210         RPC_LOG_ERROR("SendDataToRemote connect failed, sessionId=%d", sessionId);
211         return ERR_FAILED;
212     }
213 
214     if (g_trans->Send(sessionId, (void *)msg, msg->head.len) != ERR_NONE) {
215         RPC_LOG_ERROR("SendDataToRemote send failed");
216         return ERR_FAILED;
217     }
218 
219     return ERR_NONE;
220 }
221 
SendEntryToRemote(DBinderServiceStub * stub,const uint32_t seqNumber)222 static int32_t SendEntryToRemote(DBinderServiceStub *stub, const uint32_t seqNumber)
223 {
224     char *toDeviceID = stub->deviceID;
225     if (toDeviceID == NULL) {
226         RPC_LOG_ERROR("toDeviceID invalid");
227         return ERR_FAILED;
228     }
229     uint32_t toDeviceIDLength = (uint32_t)strlen(toDeviceID);
230 
231     char localDeviceID[DEVICEID_LENGTH + 1];
232     if (g_trans->GetLocalDeviceID(DBINDER_SESSION_NAME, localDeviceID) != ERR_NONE) {
233         RPC_LOG_ERROR("GetLocalDeviceID failed");
234         return ERR_FAILED;
235     }
236     uint32_t localDeviceIDLength = (uint32_t)strlen(localDeviceID);
237     if (toDeviceIDLength > DEVICEID_LENGTH || localDeviceIDLength > DEVICEID_LENGTH) {
238         RPC_LOG_ERROR("deviceID invalid");
239         return ERR_FAILED;
240     }
241 
242     DHandleEntryTxRx message = {
243         .head.len = sizeof(DHandleEntryTxRx),
244         .head.version = VERSION_NUM,
245         .transType = DATABUS_TYPE,
246         .dBinderCode = MESSAGE_AS_INVOKER,
247         .fromPort = 0,
248         .toPort = 0,
249         .stubIndex = stub->binderObject,
250         .seqNumber = seqNumber,
251         .binderObject = stub->binderObject,
252         .deviceIdInfo.afType = DATABBUS_TYPE,
253         .stub = (uintptr_t)(stub->svc.cookie),
254         .pid = (uint32_t)GetCallingPid(),
255         .uid = (uint32_t)GetCallingUid()
256     };
257     if (memcpy_s(message.deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDeviceID, localDeviceIDLength) != EOK ||
258         memcpy_s(message.deviceIdInfo.toDeviceId, DEVICEID_LENGTH, toDeviceID, toDeviceIDLength) != EOK) {
259             RPC_LOG_ERROR("deviceIdInfo memory copy failed");
260             return ERR_FAILED;
261         }
262     message.deviceIdInfo.fromDeviceId[localDeviceIDLength] = '\0';
263     message.deviceIdInfo.toDeviceId[toDeviceIDLength] = '\0';
264 
265     if (SendDataToRemote(toDeviceID, &message) != ERR_NONE) {
266         RPC_LOG_ERROR("SendDataToRemote failed");
267         return ERR_FAILED;
268     }
269     return ERR_NONE;
270 }
271 
AttachThreadLockInfo(ThreadLockInfo * threadLockInfo)272 static int32_t AttachThreadLockInfo(ThreadLockInfo *threadLockInfo)
273 {
274     pthread_mutex_lock(&g_threadLockInfoList.mutex);
275     UtilsListAdd(&g_threadLockInfoList.threadLocks, &threadLockInfo->list);
276     pthread_mutex_unlock(&g_threadLockInfoList.mutex);
277     return ERR_NONE;
278 }
279 
DetachThreadLockInfo(ThreadLockInfo * threadLockInfo)280 static void DetachThreadLockInfo(ThreadLockInfo *threadLockInfo)
281 {
282     pthread_mutex_lock(&g_threadLockInfoList.mutex);
283     UtilsListDelete(&threadLockInfo->list);
284     pthread_mutex_unlock(&g_threadLockInfoList.mutex);
285 }
286 
NewThreadLock(void)287 static ThreadLockInfo *NewThreadLock(void)
288 {
289     ThreadLockInfo *threadLockInfo = (ThreadLockInfo *)malloc(sizeof(ThreadLockInfo));
290     if (threadLockInfo == NULL) {
291         RPC_LOG_ERROR("threadLockInfo malloc failed");
292         return NULL;
293     }
294     if (pthread_mutex_init(&threadLockInfo->mutex, NULL) != 0) {
295         RPC_LOG_ERROR("threadLockInfo mutex init failed");
296         free(threadLockInfo);
297         return NULL;
298     }
299     if (pthread_cond_init(&threadLockInfo->condition, NULL) != 0) {
300         RPC_LOG_ERROR("threadLockInfo condition init failed");
301         free(threadLockInfo);
302         return NULL;
303     }
304 
305     return threadLockInfo;
306 }
307 
GetWaitTime(struct timespec * waitTime)308 static int32_t GetWaitTime(struct timespec *waitTime)
309 {
310     struct timeval now;
311     if (gettimeofday(&now, NULL) != 0) {
312         RPC_LOG_ERROR("gettimeofday failed");
313         return ERR_FAILED;
314     }
315     waitTime->tv_sec = now.tv_sec + RPC_DEFAULT_SEND_WAIT_TIME;
316     waitTime->tv_nsec = now.tv_usec * USECTONSEC;
317 
318     return ERR_NONE;
319 }
320 
InvokerRemoteDBinder(DBinderServiceStub * dBinderServiceStub,uint32_t seqNumber)321 static int32_t InvokerRemoteDBinder(DBinderServiceStub *dBinderServiceStub, uint32_t seqNumber)
322 {
323     if (dBinderServiceStub == NULL) {
324         RPC_LOG_ERROR("InvokerRemoteDBinder dBinderServiceStub is NULL");
325         return ERR_FAILED;
326     }
327 
328     int32_t ret = ERR_FAILED;
329     ThreadLockInfo *threadLockInfo = NewThreadLock();
330     if (threadLockInfo == NULL) {
331         return ret;
332     }
333     threadLockInfo->seqNumber = seqNumber;
334     ret = AttachThreadLockInfo(threadLockInfo);
335     if (ret != ERR_NONE) {
336         RPC_LOG_ERROR("AttachThreadLockInfo failed");
337         free(threadLockInfo);
338         return ret;
339     }
340 
341     pthread_mutex_lock(&threadLockInfo->mutex);
342     ret = SendEntryToRemote(dBinderServiceStub, seqNumber);
343     if (ret != ERR_NONE) {
344         RPC_LOG_ERROR("send entry to remote dbinderService failed");
345     } else {
346         struct timespec waitTime;
347         ret = GetWaitTime(&waitTime);
348         if (ret != ERR_NONE) {
349             DetachThreadLockInfo(threadLockInfo);
350             pthread_mutex_unlock(&threadLockInfo->mutex);
351             free(threadLockInfo);
352             return ERR_FAILED;
353         }
354 
355         ret = pthread_cond_timedwait(&threadLockInfo->condition, &threadLockInfo->mutex, &waitTime);
356         if (ret == ETIMEDOUT) {
357             RPC_LOG_ERROR("InvokerRemoteDBinder wait for reply timeout");
358             DetachThreadLockInfo(threadLockInfo);
359             pthread_mutex_unlock(&threadLockInfo->mutex);
360             free(threadLockInfo);
361             return ERR_FAILED;
362         }
363         RPC_LOG_INFO("InvokerRemoteDBinder wakeup!");
364     }
365 
366     if (QuerySessionObject((uintptr_t)(dBinderServiceStub->svc.cookie)) == NULL) {
367         RPC_LOG_ERROR("QuerySessionObject is null");
368         ret = ERR_FAILED;
369     }
370 
371     DetachThreadLockInfo(threadLockInfo);
372     pthread_mutex_unlock(&threadLockInfo->mutex);
373     free(threadLockInfo);
374 
375     return ret;
376 }
377 
GetSeqNumber(void)378 static uint32_t GetSeqNumber(void)
379 {
380     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
381     static uint32_t seqNumber = 0;
382     pthread_mutex_lock(&mutex);
383     seqNumber++;
384     pthread_mutex_unlock(&mutex);
385     return seqNumber;
386 }
387 
AttachSessionObject(SessionInfo * sessionInfo)388 static int32_t AttachSessionObject(SessionInfo *sessionInfo)
389 {
390     pthread_mutex_lock(&g_sessionInfoList.mutex);
391     UtilsListAdd(&g_sessionInfoList.sessionInfos, &sessionInfo->list);
392     pthread_mutex_unlock(&g_sessionInfoList.mutex);
393     return ERR_NONE;
394 }
395 
DetachSessionObject(SessionInfo * sessionInfo)396 static void DetachSessionObject(SessionInfo *sessionInfo)
397 {
398     pthread_mutex_lock(&g_sessionInfoList.mutex);
399     UtilsListDelete(&sessionInfo->list);
400     pthread_mutex_unlock(&g_sessionInfoList.mutex);
401 }
402 
QuerySessionObject(uintptr_t stub)403 SessionInfo *QuerySessionObject(uintptr_t stub)
404 {
405     SessionInfo *node = NULL;
406     pthread_mutex_lock(&g_sessionInfoList.mutex);
407     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_sessionInfoList.sessionInfos, SessionInfo, list)
408     {
409         if (node->stub == stub) {
410             pthread_mutex_unlock(&g_sessionInfoList.mutex);
411             return node;
412         }
413     }
414     pthread_mutex_unlock(&g_sessionInfoList.mutex);
415     return NULL;
416 }
417 
DeleteDBinderStub(DBinderServiceStub * stub)418 static void DeleteDBinderStub(DBinderServiceStub *stub)
419 {
420     if (stub == NULL) {
421         RPC_LOG_ERROR("DeleteDBinderStub get null stub");
422         return;
423     }
424     pthread_mutex_lock(&g_stubRegistedList.mutex);
425     UtilsListDelete(&stub->list);
426     pthread_mutex_unlock(&g_stubRegistedList.mutex);
427 }
428 
QueryProxyObject(uintptr_t binderObject)429 static ProxyObject *QueryProxyObject(uintptr_t binderObject)
430 {
431     ProxyObject *node = NULL;
432     pthread_mutex_lock(&g_proxyObjectList.mutex);
433     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_proxyObjectList.proxyObject, ProxyObject, list)
434     {
435         if (node->binderObject == binderObject) {
436             pthread_mutex_unlock(&g_proxyObjectList.mutex);
437             return node;
438         }
439     }
440     pthread_mutex_unlock(&g_proxyObjectList.mutex);
441     return NULL;
442 }
443 
AttachProxyObject(ProxyObject * proxy)444 static int32_t AttachProxyObject(ProxyObject *proxy)
445 {
446     pthread_mutex_lock(&g_proxyObjectList.mutex);
447     UtilsListAdd(&g_proxyObjectList.proxyObject, &proxy->list);
448     pthread_mutex_unlock(&g_proxyObjectList.mutex);
449     return ERR_NONE;
450 }
451 
DetachProxyObject(ProxyObject * proxy)452 static void DetachProxyObject(ProxyObject *proxy)
453 {
454     pthread_mutex_lock(&g_proxyObjectList.mutex);
455     UtilsListDelete(&proxy->list);
456     pthread_mutex_unlock(&g_proxyObjectList.mutex);
457 }
458 
DbinderSaDeathRecipient(void * args)459 static void DbinderSaDeathRecipient(void *args)
460 {
461     if (args == NULL) {
462         RPC_LOG_ERROR("DbinderSaDeathRecipient args is null");
463         return;
464     }
465     ProxyObject *proxyObject = (ProxyObject *)args;
466     RPC_LOG_INFO("DbinderSaDeathRecipient cbiId %d", proxyObject->cbId);
467     DetachProxyObject(proxyObject);
468 }
469 
FindOrNewProxy(uintptr_t binderObject,int32_t systemAbilityId)470 static ProxyObject *FindOrNewProxy(uintptr_t binderObject, int32_t systemAbilityId)
471 {
472     ProxyObject *proxyObject = QueryProxyObject(binderObject);
473     if (proxyObject != NULL) {
474         RPC_LOG_INFO("FindOrNewProxy found cached proxy");
475         return proxyObject;
476     }
477 
478     char *serviceName = GetRegisterService(binderObject);
479     if (serviceName == NULL && (systemAbilityId < FIRST_SYS_ABILITY_ID || systemAbilityId > LAST_SYS_ABILITY_ID)) {
480         RPC_LOG_ERROR("service is not registered in this device, saId:%d", systemAbilityId);
481         return NULL;
482     }
483 
484     proxyObject = RpcGetSystemAbility(systemAbilityId);
485     if (proxyObject == NULL) {
486         RPC_LOG_ERROR("RpcGetSystemAbility failed, saId: %d", systemAbilityId);
487         return NULL;
488     }
489     proxyObject->binderObject = binderObject;
490 
491     int32_t ret = AddDeathRecipient(*proxyObject->proxy, DbinderSaDeathRecipient,
492         (void *)proxyObject, &proxyObject->cbId);
493     if (ret != ERR_NONE) {
494         RPC_LOG_ERROR("FindOrNewProxy AddDeathRecipient failed, error %d", ret);
495         free(proxyObject->proxy);
496         free(proxyObject);
497         return NULL;
498     }
499 
500     if (AttachProxyObject(proxyObject) != ERR_NONE) {
501         RPC_LOG_ERROR("FindOrNewProxy AttachProxyObject failed");
502         RemoveDeathRecipient(*proxyObject->proxy, proxyObject->cbId);
503         free(proxyObject->proxy);
504         free(proxyObject);
505         return NULL;
506     }
507     return proxyObject;
508 }
509 
GetDatabusNameByProxy(ProxyObject * proxy)510 static int32_t GetDatabusNameByProxy(ProxyObject *proxy)
511 {
512     if (proxy == NULL) {
513         RPC_LOG_ERROR("GetDatabusNameByProxy proxy is null");
514         return ERR_FAILED;
515     }
516 
517     if (proxy->sessionName != NULL && strlen(proxy->sessionName) > 0) {
518         RPC_LOG_ERROR("GetDatabusNameByProxy proxy got sessionName already");
519         return ERR_NONE;
520     }
521     if (GetPidAndUidInfo(proxy) != ERR_NONE) {
522         RPC_LOG_ERROR("GetDatabusNameByProxy GetPidAndUidInfo failed");
523         return ERR_FAILED;
524     }
525     return ERR_NONE;
526 }
527 
OnRemoteInvokerDataBusMessage(ProxyObject * proxy,DHandleEntryTxRx * replyMessage,const char * remoteDeviceID,uint32_t pid,uint32_t uid)528 static int32_t OnRemoteInvokerDataBusMessage(ProxyObject *proxy, DHandleEntryTxRx *replyMessage,
529     const char *remoteDeviceID, uint32_t pid, uint32_t uid)
530 {
531     if (remoteDeviceID == NULL || strlen(remoteDeviceID) > DEVICEID_LENGTH) {
532         RPC_LOG_ERROR("remote deviceID invalid");
533         return ERR_FAILED;
534     }
535 
536     if (GetDatabusNameByProxy(proxy) != ERR_NONE) {
537         RPC_LOG_ERROR("GetDatabusNameByProxy failed");
538         return ERR_FAILED;
539     }
540 
541     char localDeviceId[DEVICEID_LENGTH + 1];
542     int32_t ret = g_trans->GetLocalDeviceID(DBINDER_SESSION_NAME, localDeviceId);
543     if (ret != ERR_NONE) {
544         RPC_LOG_ERROR("OnRemoteInvokerDataBusMessage GetLocalDeviceID failed");
545         return ERR_FAILED;
546     }
547 
548     IpcIo reply;
549     uintptr_t ptr;
550     ret = InvokerListenThread(proxy, localDeviceId, remoteDeviceID, pid, uid, &reply, &ptr);
551     if (ret != ERR_NONE) {
552         RPC_LOG_ERROR("INVOKE_LISTEN_THREAD failed");
553         FreeBuffer((void *)ptr);
554         return ERR_FAILED;
555     }
556 
557     uint64_t stubIndex;
558     if (!ReadUint64(&reply, &stubIndex)) {
559         FreeBuffer((void *)ptr);
560         return ERR_FAILED;
561     }
562 
563     size_t sessionLen;
564     char *serverSessionName = (char *)ReadString(&reply, &sessionLen);
565 
566     if (stubIndex == 0 || serverSessionName == NULL || sessionLen > SERVICENAME_LENGTH) {
567         RPC_LOG_ERROR("INVOKE_LISTEN_THREAD reply stubIndex or sessionName invalid");
568         FreeBuffer((void *)ptr);
569         return ERR_FAILED;
570     }
571 
572     replyMessage->dBinderCode = MESSAGE_AS_REPLY;
573     replyMessage->stubIndex = stubIndex;
574     replyMessage->serviceNameLength = (uint16_t)sessionLen;
575     if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName, sessionLen) != 0) {
576         RPC_LOG_ERROR("replyMessage serviceName memcpy failed");
577         FreeBuffer((void *)ptr);
578         return ERR_FAILED;
579     }
580     replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
581     FreeBuffer((void *)ptr);
582     return ERR_NONE;
583 }
584 
OnRemoteInvokerMessage(void * args)585 static void *OnRemoteInvokerMessage(void *args)
586 {
587     pthread_detach(pthread_self());
588     DHandleEntryTxRx *message = (DHandleEntryTxRx *)args;
589     ProxyObject *saProxy = FindOrNewProxy(message->binderObject, (int32_t)message->stubIndex);
590     if (saProxy == NULL) {
591         RPC_LOG_ERROR("OnRemoteInvokerMessage get SA Proxy failed");
592         return (void *)ERR_FAILED;
593     }
594 
595     DHandleEntryTxRx replyMessage;
596     if (memcpy_s(&replyMessage, sizeof(DHandleEntryTxRx), message, sizeof(DHandleEntryTxRx)) != EOK) {
597         RPC_LOG_ERROR("OnRemoteInvokerMessage replyMessage memcpy failed");
598         return (void *)ERR_FAILED;
599     }
600     char *fromDeviceID = replyMessage.deviceIdInfo.fromDeviceId;
601 
602     switch (replyMessage.transType) {
603         case DATABUS_TYPE: {
604             if (OnRemoteInvokerDataBusMessage(saProxy, &replyMessage, fromDeviceID,
605                 message->pid, message->uid) != ERR_NONE) {
606                 RPC_LOG_ERROR("OnRemoteInvokerMessage Invoker Databus Message fail");
607                 return (void *)ERR_FAILED;
608             }
609             break;
610         }
611         default: {
612             RPC_LOG_ERROR("OnRemoteInvokerMessage msg transType invalid");
613             return (void *)ERR_FAILED;
614         }
615     }
616 
617     if (SendDataToRemote(fromDeviceID, &replyMessage) != ERR_NONE) {
618         RPC_LOG_ERROR("fail to send data from server DBS to client DBS");
619         return (void *)ERR_FAILED;
620     }
621     return (void *)ERR_NONE;
622 }
623 
QueryThreadLockInfo(uint32_t seqNumber)624 static ThreadLockInfo *QueryThreadLockInfo(uint32_t seqNumber)
625 {
626     ThreadLockInfo *node = NULL;
627     pthread_mutex_lock(&g_threadLockInfoList.mutex);
628     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_threadLockInfoList.threadLocks, ThreadLockInfo, list)
629     {
630         if (node->seqNumber == seqNumber) {
631             pthread_mutex_unlock(&g_threadLockInfoList.mutex);
632             return node;
633         }
634     }
635     pthread_mutex_unlock(&g_threadLockInfoList.mutex);
636     return NULL;
637 }
638 
WakeupThreadByStub(uint32_t seqNumber)639 static void WakeupThreadByStub(uint32_t seqNumber)
640 {
641     ThreadLockInfo *threadLockInfo = QueryThreadLockInfo(seqNumber);
642     if (threadLockInfo == NULL) {
643         RPC_LOG_ERROR("threadLockInfo is not exist");
644         return;
645     }
646     pthread_mutex_lock(&threadLockInfo->mutex);
647     pthread_cond_signal(&threadLockInfo->condition);
648     pthread_mutex_unlock(&threadLockInfo->mutex);
649 }
650 
HasDBinderStub(uintptr_t binderObject)651 static bool HasDBinderStub(uintptr_t binderObject)
652 {
653     DBinderServiceStub *node;
654     pthread_mutex_lock(&g_stubRegistedList.mutex);
655     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_stubRegistedList.dBinderStubs, DBinderServiceStub, list)
656     {
657         if (node->binderObject == binderObject) {
658             pthread_mutex_unlock(&g_stubRegistedList.mutex);
659             return true;
660         }
661     }
662     pthread_mutex_unlock(&g_stubRegistedList.mutex);
663     return false;
664 }
665 
MakeSessionByReplyMessage(const DHandleEntryTxRx * replyMessage)666 static void MakeSessionByReplyMessage(const DHandleEntryTxRx *replyMessage)
667 {
668     if (replyMessage == NULL) {
669         RPC_LOG_ERROR("replyMessage is null");
670         return;
671     }
672     if (!HasDBinderStub(replyMessage->binderObject)) {
673         RPC_LOG_ERROR("invalid stub object");
674         return;
675     }
676     if (QuerySessionObject(replyMessage->stub) != NULL) {
677         RPC_LOG_ERROR("invoker remote session already, do nothing");
678         return;
679     }
680 
681     SessionInfo *session = (SessionInfo *)malloc(sizeof(SessionInfo));
682     if (session == NULL) {
683         RPC_LOG_ERROR("session malloc failed");
684         return;
685     }
686     if (memcpy_s(&session->deviceIdInfo, sizeof(struct DeviceIdInfo),
687         &replyMessage->deviceIdInfo, sizeof(struct DeviceIdInfo)) != 0) {
688         RPC_LOG_ERROR("deviceIdInfo memory copy failed");
689         free(session);
690         return;
691     }
692     if (strcpy_s(session->serviceName, SERVICENAME_LENGTH + 1, replyMessage->serviceName) != EOK) {
693         RPC_LOG_ERROR("session serviceName copy failed");
694         free(session);
695         return;
696     }
697     session->serviceName[replyMessage->serviceNameLength] = '\0';
698 
699     session->socketFd = 0;
700     session->stubIndex = replyMessage->stubIndex;
701     session->toPort = replyMessage->toPort;
702     session->fromPort = replyMessage->fromPort;
703     session->type = replyMessage->transType;
704     session->stub = replyMessage->stub;
705 
706     if (session->stubIndex == 0) {
707         RPC_LOG_ERROR("stubIndex invalid");
708         free(session);
709         return;
710     }
711     if (AttachSessionObject(session) != 0) {
712         RPC_LOG_ERROR("AttachSessionObject failed");
713         free(session);
714         return;
715     }
716 }
717 
OnRemoteReplyMessage(const DHandleEntryTxRx * replyMessage)718 static int32_t OnRemoteReplyMessage(const DHandleEntryTxRx *replyMessage)
719 {
720     MakeSessionByReplyMessage(replyMessage);
721     WakeupThreadByStub(replyMessage->seqNumber);
722     return ERR_NONE;
723 }
724 
GetSessionIdList(void)725 SessionIdList *GetSessionIdList(void)
726 {
727     return &g_sessionIdList;
728 }
729 
StartDBinderService(void)730 int32_t StartDBinderService(void)
731 {
732     static bool isDBinderCreated = false;
733     int32_t ret = ERR_NONE;
734     if (isDBinderCreated) {
735         return ret;
736     }
737 
738     g_trans = GetRpcTrans();
739     if (g_trans == NULL) {
740         RPC_LOG_ERROR("GetRpcTrans failed");
741         return ERR_FAILED;
742     }
743     ret = g_trans->StartListen(DBINDER_SESSION_NAME, (void *)GetDBinderTransCallback());
744     if (ret != ERR_NONE) {
745         RPC_LOG_ERROR("StartListen failed");
746         return ret;
747     }
748 
749     ret = InitDBinder();
750     if (ret != ERR_NONE) {
751         RPC_LOG_ERROR("InitDBinder failed");
752     }
753     isDBinderCreated = true;
754     return ret;
755 }
756 
RegisterRemoteProxy(const void * name,uint32_t len,int32_t systemAbility)757 int32_t RegisterRemoteProxy(const void *name, uint32_t len, int32_t systemAbility)
758 {
759     int32_t ret = InitDBinder();
760     if (ret != ERR_NONE) {
761         RPC_LOG_ERROR("InitDBinder failed");
762     }
763     if (name == NULL || systemAbility < 0) {
764         RPC_LOG_ERROR("RegisterRemoteProxy name is null or systemAbility invalid");
765         return ERR_FAILED;
766     }
767     const char *serviceName = (const char *)name;
768     RPC_LOG_INFO("register remote proxy, service name = %s", serviceName);
769 
770     RemoteBinderObjects *binderObject = (RemoteBinderObjects *)malloc(sizeof(RemoteBinderObjects));
771     if (binderObject == NULL) {
772         RPC_LOG_ERROR("binder object malloc failed");
773         return ERR_FAILED;
774     }
775 
776     uintptr_t binder = (uintptr_t)systemAbility;
777     binderObject->binder = binder;
778 
779     if (len == 0 || len > SERVICENAME_LENGTH || len != strlen(serviceName)) {
780         RPC_LOG_ERROR("RegisterRemoteProxy name length invalid");
781         free(binderObject);
782         return ERR_FAILED;
783     }
784     binderObject->serviceName = (char *)malloc(len + 1);
785     if (binderObject->serviceName == NULL) {
786         RPC_LOG_ERROR("RegisterRemoteProxy binderObject->serviceName malloc failed");
787         free(binderObject);
788         return ERR_FAILED;
789     }
790 
791     if (strcpy_s(binderObject->serviceName, len + 1, serviceName) != EOK) {
792         RPC_LOG_ERROR("RegisterRemoteProxy binderObject->serviceName copy failed");
793         free(binderObject->serviceName);
794         free(binderObject);
795         return ERR_FAILED;
796     }
797 
798     AddRegisterService(binderObject);
799     return ERR_NONE;
800 }
801 
MakeRemoteBinder(const void * serviceName,uint32_t nameLen,const char * deviceID,uint32_t idLen,uintptr_t binderObject,uint64_t pid,void * remoteObject)802 int32_t MakeRemoteBinder(const void *serviceName, uint32_t nameLen, const char *deviceID, uint32_t idLen,
803     uintptr_t binderObject, uint64_t pid, void *remoteObject)
804 {
805     RPC_LOG_INFO("MakeRemoteBinder start");
806     if (CheckBinderParams(serviceName, nameLen, deviceID, idLen, remoteObject) != ERR_NONE) {
807         RPC_LOG_ERROR("MakeRemoteBinder failed");
808         return ERR_FAILED;
809     }
810 
811     const char *name = (const char *)serviceName;
812     DBinderServiceStub *dBinderServiceStub  = FindOrNewDBinderStub(name, nameLen, deviceID, idLen, binderObject);
813     if (dBinderServiceStub == NULL) {
814         RPC_LOG_ERROR("FindOrNewDBinderStub return null");
815         return ERR_FAILED;
816     }
817 
818     uint32_t retryTimes = 0;
819     int32_t ret;
820     do {
821         ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber());
822         retryTimes++;
823     } while (ret != ERR_NONE && (retryTimes < RETRY_TIMES));
824 
825     if (ret != ERR_NONE) {
826         RPC_LOG_ERROR("fail to invoke service, service name = %s", serviceName);
827         SessionInfo *sessionObject = QuerySessionObject((uintptr_t)(dBinderServiceStub->svc.cookie));
828         if (sessionObject != NULL) {
829             DetachSessionObject(sessionObject);
830             free(sessionObject);
831         }
832         DeleteDBinderStub(dBinderServiceStub);
833         free((void *)dBinderServiceStub->svc.cookie);
834         free(dBinderServiceStub);
835     } else {
836         if (memcpy_s(remoteObject, sizeof(SvcIdentity), &dBinderServiceStub->svc, sizeof(SvcIdentity)) != 0) {
837             RPC_LOG_ERROR("svc memory copy failed");
838             ret = ERR_FAILED;
839         }
840     }
841 
842     return ret;
843 }
844 
OnRemoteMessageTask(const DHandleEntryTxRx * message)845 int32_t OnRemoteMessageTask(const DHandleEntryTxRx *message)
846 {
847     if (message == NULL) {
848         RPC_LOG_ERROR("OnRemoteMessageTask message is NULL");
849         return ERR_FAILED;
850     }
851 
852     int32_t ret;
853     switch (message->dBinderCode) {
854         case MESSAGE_AS_INVOKER: {
855             pthread_t threadId;
856             ret = pthread_create(&threadId, NULL, OnRemoteInvokerMessage, (void *)message);
857             if (ret != 0) {
858                 RPC_LOG_ERROR("OnRemoteMessageTask pthread_create failed %d", ret);
859                 ret = ERR_FAILED;
860                 break;
861             }
862 
863             ret = ERR_NONE;
864             break;
865         }
866         case MESSAGE_AS_REPLY: {
867             ret = OnRemoteReplyMessage(message);
868             break;
869         }
870         default: {
871             RPC_LOG_ERROR("OnRemoteMessageTask dbindercode=%d valid", message->dBinderCode);
872             ret = ERR_FAILED;
873             break;
874         }
875     }
876     return ret;
877 }
878