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