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