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
38typedef struct {
39    UTILS_DL_LIST list;
40    char *serviceName;
41    uintptr_t binder;
42} RemoteBinderObjects;
43
44typedef struct {
45    UTILS_DL_LIST remoteBinderObjects;
46    pthread_mutex_t mutex;
47} RemoteBinderObjectsList;
48
49typedef struct {
50    UTILS_DL_LIST dBinderStubs;
51    pthread_mutex_t mutex;
52} DBinderStubRegistedList;
53
54typedef struct {
55    UTILS_DL_LIST list;
56    pthread_mutex_t mutex;
57    pthread_cond_t condition;
58    uint32_t seqNumber;
59} ThreadLockInfo;
60
61typedef struct {
62    UTILS_DL_LIST threadLocks;
63    pthread_mutex_t mutex;
64} ThreadLockInfoList;
65
66typedef struct {
67    UTILS_DL_LIST sessionInfos;
68    pthread_mutex_t mutex;
69} SessionInfoList;
70
71typedef struct {
72    UTILS_DL_LIST proxyObject;
73    pthread_mutex_t mutex;
74} ProxyObjectList;
75
76static RemoteBinderObjectsList g_binderList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
77static DBinderStubRegistedList g_stubRegistedList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
78static ThreadLockInfoList g_threadLockInfoList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
79static SessionInfoList g_sessionInfoList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
80static ProxyObjectList g_proxyObjectList = {.mutex = PTHREAD_MUTEX_INITIALIZER};
81static SessionIdList g_sessionIdList = {
82    .mutex = PTHREAD_MUTEX_INITIALIZER,
83    .condition = PTHREAD_COND_INITIALIZER
84};
85
86static TransInterface *g_trans = NULL;
87static char const *DBINDER_SESSION_NAME = "DBinderService";
88static const uint32_t RETRY_TIMES = 2;
89static const int32_t FIRST_SYS_ABILITY_ID = 0x00000001;
90static const int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
91static int g_listInit = 0;
92
93static 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
107static 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
122static 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
129static 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
144static 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
161static 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
168static 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
197static 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
222static 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
272static 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
280static 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
287static 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
308static 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
321static 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
378static 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
388static 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
396static 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
403SessionInfo *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
418static 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
429static 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
444static 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
452static 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
459static 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
470static 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
510static 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
528static 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
585static 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
624static 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
639static 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
651static 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
666static 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
718static int32_t OnRemoteReplyMessage(const DHandleEntryTxRx *replyMessage)
719{
720    MakeSessionByReplyMessage(replyMessage);
721    WakeupThreadByStub(replyMessage->seqNumber);
722    return ERR_NONE;
723}
724
725SessionIdList *GetSessionIdList(void)
726{
727    return &g_sessionIdList;
728}
729
730int32_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
757int32_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
802int32_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
845int32_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