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