• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "securec.h"
18 #include "string_ex.h"
19 #include "ipc_skeleton.h"
20 #include "ipc_thread_skeleton.h"
21 
22 #include "dbinder_log.h"
23 #include "dbinder_service_stub.h"
24 #include "dbinder_remote_listener.h"
25 #include "dbinder_error_code.h"
26 #include "softbus_bus_center.h"
27 #include "dbinder_sa_death_recipient.h"
28 
29 namespace OHOS {
30 using namespace Communication;
31 
32 sptr<DBinderService> DBinderService::instance_ = nullptr;
33 bool DBinderService::mainThreadCreated_ = false;
34 std::mutex DBinderService::instanceMutex_;
35 std::shared_ptr<DBinderRemoteListener> DBinderService::remoteListener_ = nullptr;
36 
DBinderService()37 DBinderService::DBinderService()
38 {
39     DBINDER_LOGI("create dbinder service");
40 }
41 
~DBinderService()42 DBinderService::~DBinderService()
43 {
44     StopRemoteListener();
45 
46     DBinderStubRegisted_.clear();
47     mapRemoteBinderObjects_.clear();
48     threadLockInfo_.clear();
49     proxyObject_.clear();
50     sessionObject_.clear();
51     noticeProxy_.clear();
52     deathRecipients_.clear();
53     busNameObject_.clear();
54     dbinderCallback_ = nullptr;
55 
56     DBINDER_LOGI("dbinder service died");
57 }
58 
GetLocalDeviceID()59 std::string DBinderService::GetLocalDeviceID()
60 {
61     std::string pkgName = "DBinderService";
62     NodeBasicInfo nodeBasicInfo;
63     if (GetLocalNodeDeviceInfo(pkgName.c_str(), &nodeBasicInfo) != 0) {
64         DBINDER_LOGE("Get local node device info failed");
65         return "";
66     }
67     std::string networkId(nodeBasicInfo.networkId);
68     return networkId;
69 }
70 
StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> & callbackImpl)71 bool DBinderService::StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl)
72 {
73     if (mainThreadCreated_) {
74         return true;
75     }
76 
77     bool result = StartRemoteListener();
78     if (!result) {
79         return false;
80     }
81     mainThreadCreated_ = true;
82     dbinderCallback_ = callbackImpl;
83 
84     return true;
85 }
86 
StartRemoteListener()87 bool DBinderService::StartRemoteListener()
88 {
89     if (remoteListener_ != nullptr) {
90         DBINDER_LOGI("remote listener started");
91         return true;
92     }
93 
94     remoteListener_ = std::make_shared<DBinderRemoteListener>(GetInstance());
95     if (remoteListener_ == nullptr) {
96         DBINDER_LOGE("failed to create remote listener");
97         return false;
98     }
99 
100     if (remoteListener_->StartListener(remoteListener_) != true) {
101         StopRemoteListener();
102         return false;
103     }
104 
105     DBINDER_LOGI("start remote listener ok");
106     return true;
107 }
108 
StopRemoteListener()109 void DBinderService::StopRemoteListener()
110 {
111     if (remoteListener_ != nullptr) {
112         remoteListener_->StopListener();
113         remoteListener_ = nullptr;
114     }
115 }
116 
GetRemoteListener()117 std::shared_ptr<DBinderRemoteListener> DBinderService::GetRemoteListener()
118 {
119     if (remoteListener_ == nullptr && !StartRemoteListener()) {
120         return nullptr;
121     }
122     return remoteListener_;
123 }
124 
GetInstance()125 sptr<DBinderService> DBinderService::GetInstance()
126 {
127     if (instance_ == nullptr) {
128         std::lock_guard<std::mutex> lockGuard(instanceMutex_);
129         if (instance_ == nullptr) {
130             sptr<DBinderService> temp = new DBinderService();
131             instance_ = temp;
132         }
133     }
134 
135     return instance_;
136 }
137 
GetSeqNumber()138 uint32_t DBinderService::GetSeqNumber()
139 {
140     std::lock_guard<std::mutex> lockGuard(instanceMutex_);
141     seqNumber_++; // can be overflow
142     return seqNumber_;
143 }
144 
IsDeviceIdIllegal(const std::string & deviceID)145 bool DBinderService::IsDeviceIdIllegal(const std::string &deviceID)
146 {
147     if (deviceID.empty() || deviceID.length() > DEVICEID_LENGTH) {
148         return true;
149     }
150     return false;
151 }
152 
CheckBinderObject(const sptr<DBinderServiceStub> & stub,binder_uintptr_t binderObject)153 bool DBinderService::CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t binderObject)
154 {
155     if (stub == nullptr) {
156         return false;
157     }
158 
159     if (stub->GetBinderObject() == binderObject) {
160         DBINDER_LOGI("found registered stub");
161         return true;
162     }
163     return false;
164 }
165 
HasDBinderStub(binder_uintptr_t binderObject)166 bool DBinderService::HasDBinderStub(binder_uintptr_t binderObject)
167 {
168     auto checkStub = [&binderObject, this](const sptr<DBinderServiceStub> &stub) {
169         return CheckBinderObject(stub, binderObject);
170     };
171 
172     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
173     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
174     if (it != DBinderStubRegisted_.end()) {
175         return true;
176     }
177     return false;
178 }
179 
IsSameStubObject(const sptr<DBinderServiceStub> & stub,const std::u16string & service,const std::string & device)180 bool DBinderService::IsSameStubObject(const sptr<DBinderServiceStub> &stub, const std::u16string &service,
181     const std::string &device)
182 {
183     if (stub == nullptr) {
184         return false;
185     }
186     if (IsSameTextStr(stub->GetServiceName(), Str16ToStr8(service)) && IsSameTextStr(stub->GetDeviceID(), device)) {
187         DBINDER_LOGI("found registered service with name = %s", Str16ToStr8(service).c_str());
188         return true;
189     }
190     return false;
191 }
FindDBinderStub(const std::u16string & service,const std::string & device)192 sptr<DBinderServiceStub> DBinderService::FindDBinderStub(const std::u16string &service, const std::string &device)
193 {
194     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
195         return IsSameStubObject(stub, service, device);
196     };
197 
198     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
199     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
200     if (it == DBinderStubRegisted_.end()) {
201         return nullptr;
202     }
203     return (*it);
204 }
205 
DeleteDBinderStub(const std::u16string & service,const std::string & device)206 bool DBinderService::DeleteDBinderStub(const std::u16string &service, const std::string &device)
207 {
208     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
209         return IsSameStubObject(stub, service, device);
210     };
211 
212     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
213     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
214     if (it == DBinderStubRegisted_.end()) {
215         return false;
216     }
217     DBinderStubRegisted_.erase(it);
218     return true;
219 }
220 
FindOrNewDBinderStub(const std::u16string & service,const std::string & device,binder_uintptr_t binderObject)221 sptr<DBinderServiceStub> DBinderService::FindOrNewDBinderStub(const std::u16string &service, const std::string &device,
222     binder_uintptr_t binderObject)
223 {
224     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
225         return IsSameStubObject(stub, service, device);
226     };
227 
228     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
229     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
230     if (it != DBinderStubRegisted_.end()) {
231         return (*it);
232     }
233 
234     sptr<DBinderServiceStub> dBinderServiceStub = new DBinderServiceStub(Str16ToStr8(service), device, binderObject);
235     DBinderStubRegisted_.push_back(dBinderServiceStub);
236     return dBinderServiceStub;
237 }
238 
MakeRemoteBinder(const std::u16string & serviceName,const std::string & deviceID,binder_uintptr_t binderObject,uint64_t pid)239 sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &serviceName,
240     const std::string &deviceID, binder_uintptr_t binderObject, uint64_t pid)
241 {
242     if (IsDeviceIdIllegal(deviceID) || serviceName.length() == 0) {
243         DBINDER_LOGE("para is wrong device id length = %zu, service name length = %zu", deviceID.length(),
244             serviceName.length());
245         return nullptr;
246     }
247     DBINDER_LOGI("name = %{public}s, deviceID = %{public}s", Str16ToStr8(serviceName).c_str(),
248         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
249 
250     sptr<DBinderServiceStub> dBinderServiceStub = FindOrNewDBinderStub(serviceName, deviceID, binderObject);
251     if (dBinderServiceStub == nullptr) {
252         DBINDER_LOGE("fail to find or new service, service name = %{public}s", Str16ToStr8(serviceName).c_str());
253         return nullptr;
254     }
255 
256     /* if not found dBinderServiceStub, should send msg to toDeviceID
257      * to invoker socket thread and add authentication info for create softbus session
258      */
259     int retryTimes = 0;
260     bool ret = false;
261     do {
262         ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber());
263         retryTimes++;
264     } while (!ret && (retryTimes < RETRY_TIMES));
265 
266     if (!ret) {
267         DBINDER_LOGE("fail to invoke service, service name = %{public}s", Str16ToStr8(serviceName).c_str());
268         /* invoke fail, delete dbinder stub info */
269         (void)DeleteDBinderStub(serviceName, deviceID);
270         (void)DetachSessionObject(reinterpret_cast<binder_uintptr_t>(dBinderServiceStub.GetRefPtr()));
271         return nullptr;
272     }
273 
274     return dBinderServiceStub;
275 }
276 
SendEntryToRemote(const sptr<DBinderServiceStub> stub,uint32_t seqNumber)277 bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber)
278 {
279     const std::string deviceID = stub->GetDeviceID();
280     const std::string localDevID = GetLocalDeviceID();
281     if (IsDeviceIdIllegal(deviceID) || IsDeviceIdIllegal(localDevID)) {
282         DBINDER_LOGE("wrong device ID");
283         return false;
284     }
285 
286     std::shared_ptr<struct DHandleEntryTxRx> message = std::make_shared<struct DHandleEntryTxRx>();
287     message->head.len            = sizeof(DHandleEntryTxRx);
288     message->head.version        = VERSION_NUM;
289     message->dBinderCode         = MESSAGE_AS_INVOKER;
290     message->transType           = GetRemoteTransType();
291     message->fromPort            = 0;
292     message->toPort              = 0;
293     message->stubIndex           = static_cast<uint64_t>(std::atoi(stub->GetServiceName().c_str()));
294     message->seqNumber           = seqNumber;
295     message->binderObject        = stub->GetBinderObject();
296     message->stub                = reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr());
297     message->deviceIdInfo.afType = DATABBUS_TYPE;
298     message->pid                 = static_cast<uint32_t>(IPCSkeleton::GetCallingPid());
299     message->uid                 = static_cast<uint32_t>(IPCSkeleton::GetCallingUid());
300     if (memcpy_s(message->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDevID.data(), localDevID.length()) != 0 ||
301         memcpy_s(message->deviceIdInfo.toDeviceId, DEVICEID_LENGTH, deviceID.data(), deviceID.length()) != 0) {
302         DBINDER_LOGE("fail to copy memory");
303         return false;
304     }
305     message->deviceIdInfo.fromDeviceId[localDevID.length()] = '\0';
306     message->deviceIdInfo.toDeviceId[deviceID.length()] = '\0';
307 
308     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
309     if (remoteListener == nullptr) {
310         DBINDER_LOGE("remoteListener is null");
311         return false;
312     }
313     bool result = remoteListener->SendDataToRemote(deviceID, message.get());
314     if (result != true) {
315         DBINDER_LOGE("send to remote dbinderService failed");
316         return false;
317     }
318     return true;
319 }
320 
InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub,uint32_t seqNumber)321 bool DBinderService::InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber)
322 {
323     if (stub == nullptr) {
324         DBINDER_LOGE("stub is nullptr");
325         return false;
326     }
327     bool result = SendEntryToRemote(stub, seqNumber);
328     if (!result) {
329         DBINDER_LOGE("send entry to remote dbinderService fail");
330         return false;
331     }
332 
333     /* pend to wait reply */
334     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = std::make_shared<struct ThreadLockInfo>();
335     result = AttachThreadLockInfo(seqNumber, threadLockInfo);
336     if (result != true) {
337         DBINDER_LOGE("attach lock info fail");
338         return false;
339     }
340 
341     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
342     if (threadLockInfo->condition.wait_for(lock, std::chrono::seconds(WAIT_FOR_REPLY_MAX_SEC),
343         [&threadLockInfo] { return threadLockInfo->ready; }) == false) {
344         DBINDER_LOGE("get remote data failed");
345         DetachThreadLockInfo(seqNumber);
346         threadLockInfo->ready = false;
347         return false;
348     }
349     /* if can not find session, means invoke failed or nothing in OnRemoteReplyMessage() */
350     auto session = QuerySessionObject(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
351     if (session == nullptr) {
352         DBINDER_LOGE("client find session is null");
353         return false;
354     }
355     return true;
356 }
357 
CheckSystemAbilityId(int32_t systemAbilityId)358 bool DBinderService::CheckSystemAbilityId(int32_t systemAbilityId)
359 {
360     return systemAbilityId >= FIRST_SYS_ABILITY_ID && systemAbilityId <= LAST_SYS_ABILITY_ID;
361 }
362 
FindOrNewProxy(binder_uintptr_t binderObject,int32_t systemAbilityId)363 sptr<IRemoteObject> DBinderService::FindOrNewProxy(binder_uintptr_t binderObject, int32_t systemAbilityId)
364 {
365     sptr<IRemoteObject> proxy = QueryProxyObject(binderObject);
366     if (proxy != nullptr) {
367         DBINDER_LOGI("already have proxy");
368         return proxy;
369     }
370     if (dbinderCallback_ == nullptr) {
371         DBINDER_LOGE("samgr not initialized get remote sa callback");
372         return nullptr;
373     }
374     /* proxy is null, attempt to get a new proxy */
375     std::u16string serviceName = GetRegisterService(binderObject);
376     if (serviceName.empty() && !CheckSystemAbilityId(systemAbilityId)) {
377         DBINDER_LOGE("service is not registered in this device, saId:%{public}d", systemAbilityId);
378         return nullptr;
379     }
380     int32_t digitalName = !serviceName.empty() ? std::atoi(Str16ToStr8(serviceName).c_str()) : systemAbilityId;
381     proxy = dbinderCallback_->GetSystemAbilityFromRemote(digitalName);
382     if (proxy != nullptr) {
383         /* When the stub object dies, you need to delete the corresponding busName information */
384         IPCObjectProxy *saProxy = reinterpret_cast<IPCObjectProxy *>(proxy.GetRefPtr());
385         sptr<IRemoteObject::DeathRecipient> death(new DbinderSaDeathRecipient(binderObject));
386         if (!saProxy->AddDeathRecipient(death)) {
387             DBINDER_LOGE("fail to add death recipient");
388             return nullptr;
389         }
390         bool ret = AttachProxyObject(proxy, binderObject);
391         if (!ret) {
392             DBINDER_LOGE("attach proxy object fail");
393             return nullptr;
394         }
395     } else {
396         DBINDER_LOGW("GetSystemAbility from samgr error, saId:%{public}d", digitalName);
397     }
398     return proxy;
399 }
AllocFreeSocketPort()400 uint16_t DBinderService::AllocFreeSocketPort()
401 {
402     /* alloc port by system */
403     return 0;
404 }
405 
OnRemoteInvokerMessage(const struct DHandleEntryTxRx * message)406 bool DBinderService::OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message)
407 {
408     sptr<IRemoteObject> proxy = FindOrNewProxy(message->binderObject, static_cast<int32_t>(message->stubIndex));
409     if (proxy == nullptr) {
410         DBINDER_LOGE("find and new proxy fail");
411         return false;
412     }
413     IPCObjectProxy *ipcProxy = reinterpret_cast<IPCObjectProxy *>(proxy.GetRefPtr());
414     std::shared_ptr<struct DHandleEntryTxRx> replyMessage = std::make_shared<struct DHandleEntryTxRx>();
415     if (memcpy_s(replyMessage.get(), sizeof(DHandleEntryTxRx), message, sizeof(DHandleEntryTxRx)) != 0) {
416         DBINDER_LOGE("fail to copy memory");
417         return false;
418     }
419     std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId;
420 
421     switch (replyMessage->transType) {
422         case IRemoteObject::DATABUS_TYPE: {
423             if (!OnRemoteInvokerDataBusMessage(ipcProxy, replyMessage.get(), deviceId, message->pid, message->uid)) {
424                 DBINDER_LOGE("Invoker Databus Message fail");
425                 return false;
426             }
427             break;
428         }
429         default: {
430             DBINDER_LOGE("Invalid Message Type");
431             return false;
432         }
433     }
434     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
435     if (remoteListener == nullptr) {
436         DBINDER_LOGE("remoteListener is null");
437         return false;
438     }
439     bool ret = remoteListener->SendDataToRemote(deviceId, replyMessage.get());
440     if (ret != true) {
441         DBINDER_LOGE("fail to send data from server DBS to client DBS");
442         return false;
443     }
444 
445     return true;
446 }
447 
GetDatabusNameByProxy(IPCObjectProxy * proxy)448 std::string DBinderService::GetDatabusNameByProxy(IPCObjectProxy *proxy)
449 {
450     if (proxy == nullptr) {
451         DBINDER_LOGE("proxy can not be null");
452         return "";
453     }
454     std::string sessionName = QueryBusNameObject(proxy);
455     if (!sessionName.empty()) {
456         DBINDER_LOGI("sessionName has been granded");
457         return sessionName;
458     }
459     sessionName = proxy->GetPidAndUidInfo();
460     if (sessionName.empty()) {
461         DBINDER_LOGE("grand session name failed");
462         return "";
463     }
464     return sessionName;
465 }
466 
CreateDatabusName(int uid,int pid)467 std::string DBinderService::CreateDatabusName(int uid, int pid)
468 {
469     std::shared_ptr<ISessionService> softbusManager = ISessionService::GetInstance();
470     if (softbusManager == nullptr) {
471         DBINDER_LOGE("fail to get softbus service");
472         return "";
473     }
474 
475     std::string sessionName = "DBinder" + std::to_string(uid) + std::string("_") + std::to_string(pid);
476     if (softbusManager->GrantPermission(uid, pid, sessionName) != ERR_NONE) {
477         DBINDER_LOGE("fail to Grant Permission softbus name");
478         return "";
479     }
480 
481     return sessionName;
482 }
483 
OnRemoteInvokerDataBusMessage(IPCObjectProxy * proxy,struct DHandleEntryTxRx * replyMessage,std::string & remoteDeviceId,int pid,int uid)484 bool DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage,
485     std::string &remoteDeviceId, int pid, int uid)
486 {
487     if (IsDeviceIdIllegal(remoteDeviceId)) {
488         DBINDER_LOGE("remote device id is error");
489         return false;
490     }
491     std::string sessionName = GetDatabusNameByProxy(proxy);
492     if (sessionName.empty()) {
493         DBINDER_LOGE("get bus name fail");
494         return false;
495     }
496 
497     MessageParcel data;
498     MessageParcel reply;
499     if (!data.WriteUint16(IRemoteObject::DATABUS_TYPE) || !data.WriteString(GetLocalDeviceID()) ||
500         !data.WriteUint32(pid) || !data.WriteUint32(uid) || !data.WriteString(remoteDeviceId) ||
501         !data.WriteString(sessionName)) {
502         DBINDER_LOGE("write to parcel fail");
503         return false;
504     }
505     int err = proxy->InvokeListenThread(data, reply);
506     if (err != ERR_NONE) {
507         DBINDER_LOGE("start service listen error = %d", err);
508         return false;
509     }
510     uint64_t stubIndex = reply.ReadUint64();
511     std::string serverSessionName = reply.ReadString();
512     if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) {
513         DBINDER_LOGE("stubindex or session name invalid");
514         return false;
515     }
516 
517     replyMessage->dBinderCode = MESSAGE_AS_REPLY;
518     replyMessage->stubIndex = stubIndex;
519     replyMessage->serviceNameLength = serverSessionName.length();
520     if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(),
521         replyMessage->serviceNameLength) != 0) {
522         DBINDER_LOGE("fail to copy memory");
523         return false;
524     }
525     replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
526 
527     (void)AttachBusNameObject(proxy, serverSessionName);
528     return true;
529 }
530 
GetRegisterService(binder_uintptr_t binderObject)531 std::u16string DBinderService::GetRegisterService(binder_uintptr_t binderObject)
532 {
533     DBINDER_LOGI("get service binderObject");
534     std::shared_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
535     for (auto it = mapRemoteBinderObjects_.begin(); it != mapRemoteBinderObjects_.end(); it++) {
536         if (it->second == binderObject) {
537             return it->first;
538         }
539     }
540 
541     return std::u16string();
542 }
543 
RegisterRemoteProxy(std::u16string serviceName,sptr<IRemoteObject> binderObject)544 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject)
545 {
546     DBINDER_LOGI("register remote proxy, service name = %{public}s", Str16ToStr8(serviceName).c_str());
547 
548     if (serviceName.length() == 0 || binderObject == nullptr) {
549         DBINDER_LOGE("serviceName.length() = %zu", serviceName.length());
550         return false;
551     }
552 
553     binder_uintptr_t binder = (binder_uintptr_t)binderObject.GetRefPtr();
554     DBINDER_LOGI("register remote proxy");
555     return RegisterRemoteProxyInner(serviceName, binder);
556 }
557 
RegisterRemoteProxy(std::u16string serviceName,int32_t systemAbilityId)558 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId)
559 {
560     DBINDER_LOGI("register remote proxy, service name = %{public}s", Str16ToStr8(serviceName).c_str());
561 
562     if (serviceName.length() == 0 || systemAbilityId <= 0) {
563         DBINDER_LOGE("serviceName.length() = %zu", serviceName.length());
564         return false;
565     }
566 
567     binder_uintptr_t binder = (binder_uintptr_t)systemAbilityId;
568     return RegisterRemoteProxyInner(serviceName, binder);
569 }
570 
RegisterRemoteProxyInner(std::u16string serviceName,binder_uintptr_t binder)571 bool DBinderService::RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder)
572 {
573     std::unique_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
574     // clear historical remnants, Don't care if it succeeds
575     (void)mapRemoteBinderObjects_.erase(serviceName);
576     auto result = mapRemoteBinderObjects_.insert(std::pair<std::u16string, binder_uintptr_t>(serviceName, binder));
577     return result.second;
578 }
579 
OnRemoteMessageTask(const struct DHandleEntryTxRx * message)580 bool DBinderService::OnRemoteMessageTask(const struct DHandleEntryTxRx *message)
581 {
582     if (message == nullptr) {
583         DBINDER_LOGE("message is null ");
584         return false;
585     }
586 
587     bool result = false;
588     switch (message->dBinderCode) {
589         case MESSAGE_AS_INVOKER: {
590             result = OnRemoteInvokerMessage(message);
591             break;
592         }
593         case MESSAGE_AS_REPLY: {
594             result = OnRemoteReplyMessage(message);
595             break;
596         }
597         default: {
598             DBINDER_LOGE("ERROR! DbinderCode is wrong value, code =%u", message->dBinderCode);
599             result = false;
600             break;
601         }
602     }
603     return result;
604 }
605 
OnRemoteReplyMessage(const struct DHandleEntryTxRx * replyMessage)606 bool DBinderService::OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage)
607 {
608     MakeSessionByReplyMessage(replyMessage);
609     WakeupThreadByStub(replyMessage->seqNumber);
610     DetachThreadLockInfo(replyMessage->seqNumber);
611     return true;
612 }
613 
MakeSessionByReplyMessage(const struct DHandleEntryTxRx * replyMessage)614 void DBinderService::MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage)
615 {
616     if (HasDBinderStub(replyMessage->binderObject) == false) {
617         DBINDER_LOGE("invalid stub object");
618         return;
619     }
620     if (QuerySessionObject(replyMessage->stub) != nullptr) {
621         DBINDER_LOGI("invoker remote session already, do nothing");
622         return;
623     }
624     std::shared_ptr<struct SessionInfo> session = std::make_shared<struct SessionInfo>();
625     if (session == nullptr) {
626         DBINDER_LOGE("new SessionInfo fail");
627         return;
628     }
629 
630     if (memcpy_s(&session->deviceIdInfo, sizeof(struct DeviceIdInfo), &replyMessage->deviceIdInfo,
631         sizeof(struct DeviceIdInfo)) != 0) {
632         DBINDER_LOGE("fail to copy memory");
633         return;
634     }
635     session->socketFd    = 0;
636     session->stubIndex   = replyMessage->stubIndex;
637     session->toPort      = replyMessage->toPort;
638     session->fromPort    = replyMessage->fromPort;
639     session->type        = replyMessage->transType;
640     session->serviceName = replyMessage->serviceName;
641 
642     if (session->stubIndex == 0) {
643         DBINDER_LOGE("get stub index == 0, it is invalid");
644         return;
645     }
646 
647     if (!AttachSessionObject(session, replyMessage->stub)) {
648         DBINDER_LOGE("attach SessionInfo fail");
649         return;
650     }
651 }
652 
WakeupThreadByStub(uint32_t seqNumber)653 void DBinderService::WakeupThreadByStub(uint32_t seqNumber)
654 {
655     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = QueryThreadLockInfo(seqNumber);
656     if (threadLockInfo == nullptr) {
657         DBINDER_LOGE("threadLockInfo is not exist");
658         return;
659     }
660     /* Wake up the client processing thread */
661     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
662     threadLockInfo->ready = true;
663     threadLockInfo->condition.notify_all();
664 }
665 
DetachThreadLockInfo(uint32_t seqNumber)666 void DBinderService::DetachThreadLockInfo(uint32_t seqNumber)
667 {
668     std::lock_guard<std::mutex> lock(threadLockMutex_);
669     threadLockInfo_.erase(seqNumber);
670 }
671 
AttachThreadLockInfo(uint32_t seqNumber,std::shared_ptr<struct ThreadLockInfo> object)672 bool DBinderService::AttachThreadLockInfo(uint32_t seqNumber, std::shared_ptr<struct ThreadLockInfo> object)
673 {
674     std::lock_guard<std::mutex> lock(threadLockMutex_);
675     auto result =
676         threadLockInfo_.insert(std::pair<uint32_t, std::shared_ptr<struct ThreadLockInfo>>(seqNumber, object));
677 
678     return result.second;
679 }
680 
QueryThreadLockInfo(uint32_t seqNumber)681 std::shared_ptr<struct ThreadLockInfo> DBinderService::QueryThreadLockInfo(uint32_t seqNumber)
682 {
683     std::lock_guard<std::mutex> lock(threadLockMutex_);
684 
685     auto it = threadLockInfo_.find(seqNumber);
686     if (it != threadLockInfo_.end()) {
687         return it->second;
688     }
689     return nullptr;
690 }
691 
692 
DetachProxyObject(binder_uintptr_t binderObject)693 bool DBinderService::DetachProxyObject(binder_uintptr_t binderObject)
694 {
695     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
696 
697     return (proxyObject_.erase(binderObject) > 0);
698 }
699 
AttachProxyObject(sptr<IRemoteObject> object,binder_uintptr_t binderObject)700 bool DBinderService::AttachProxyObject(sptr<IRemoteObject> object, binder_uintptr_t binderObject)
701 {
702     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
703 
704     auto result = proxyObject_.insert(std::pair<int, sptr<IRemoteObject>>(binderObject, object));
705     return result.second;
706 }
707 
QueryProxyObject(binder_uintptr_t binderObject)708 sptr<IRemoteObject> DBinderService::QueryProxyObject(binder_uintptr_t binderObject)
709 {
710     std::shared_lock<std::shared_mutex> lock(proxyMutex_);
711 
712     auto it = proxyObject_.find(binderObject);
713     if (it != proxyObject_.end()) {
714         return it->second;
715     }
716     return nullptr;
717 }
718 
DetachSessionObject(binder_uintptr_t stub)719 bool DBinderService::DetachSessionObject(binder_uintptr_t stub)
720 {
721     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
722 
723     return (sessionObject_.erase(stub) > 0);
724 }
725 
AttachSessionObject(std::shared_ptr<struct SessionInfo> object,binder_uintptr_t stub)726 bool DBinderService::AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub)
727 {
728     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
729 
730     auto ret = sessionObject_.insert(std::pair<binder_uintptr_t, std::shared_ptr<struct SessionInfo>>(stub, object));
731 
732     return ret.second;
733 }
734 
QuerySessionObject(binder_uintptr_t stub)735 std::shared_ptr<struct SessionInfo> DBinderService::QuerySessionObject(binder_uintptr_t stub)
736 {
737     std::shared_lock<std::shared_mutex> lock(sessionMutex_);
738 
739     auto it = sessionObject_.find(stub);
740     if (it != sessionObject_.end()) {
741         return it->second;
742     }
743     return nullptr;
744 }
745 
DetachBusNameObject(IPCObjectProxy * proxy)746 bool DBinderService::DetachBusNameObject(IPCObjectProxy *proxy)
747 {
748     std::unique_lock<std::shared_mutex> lock(busNameMutex_);
749 
750     return (busNameObject_.erase(proxy) > 0);
751 }
752 
AttachBusNameObject(IPCObjectProxy * proxy,const std::string & name)753 bool DBinderService::AttachBusNameObject(IPCObjectProxy *proxy, const std::string &name)
754 {
755     std::unique_lock<std::shared_mutex> lock(busNameMutex_);
756 
757     auto ret = busNameObject_.insert(std::pair<IPCObjectProxy *, std::string>(proxy, name));
758 
759     return ret.second;
760 }
761 
QueryBusNameObject(IPCObjectProxy * proxy)762 std::string DBinderService::QueryBusNameObject(IPCObjectProxy *proxy)
763 {
764     std::shared_lock<std::shared_mutex> lock(busNameMutex_);
765 
766     auto it = busNameObject_.find(proxy);
767     if (it != busNameObject_.end()) {
768         return it->second;
769     }
770     return "";
771 }
772 
DetachDeathRecipient(sptr<IRemoteObject> object)773 bool DBinderService::DetachDeathRecipient(sptr<IRemoteObject> object)
774 {
775     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
776 
777     return (deathRecipients_.erase(object) > 0);
778 }
779 
AttachDeathRecipient(sptr<IRemoteObject> object,sptr<IRemoteObject::DeathRecipient> deathRecipient)780 bool DBinderService::AttachDeathRecipient(sptr<IRemoteObject> object,
781     sptr<IRemoteObject::DeathRecipient> deathRecipient)
782 {
783     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
784 
785     auto ret = deathRecipients_.insert(
786         std::pair<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>>(object, deathRecipient));
787 
788     return ret.second;
789 }
790 
QueryDeathRecipient(sptr<IRemoteObject> object)791 sptr<IRemoteObject::DeathRecipient> DBinderService::QueryDeathRecipient(sptr<IRemoteObject> object)
792 {
793     std::shared_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
794 
795     auto it = deathRecipients_.find(object);
796     if (it != deathRecipients_.end()) {
797         return it->second;
798     }
799 
800     return nullptr;
801 }
802 
803 
DetachCallbackProxy(sptr<IRemoteObject> object)804 bool DBinderService::DetachCallbackProxy(sptr<IRemoteObject> object)
805 {
806     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
807 
808     return (noticeProxy_.erase(object) > 0);
809 }
810 
AttachCallbackProxy(sptr<IRemoteObject> object,DBinderServiceStub * dbStub)811 bool DBinderService::AttachCallbackProxy(sptr<IRemoteObject> object, DBinderServiceStub *dbStub)
812 {
813     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
814 
815     auto result = noticeProxy_.insert(std::pair<sptr<IRemoteObject>, DBinderServiceStub *>(object, dbStub));
816 
817     return result.second;
818 }
819 
NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)820 bool DBinderService::NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)
821 {
822     bool status = true;
823     const binder_uintptr_t binderObject = reinterpret_cast<binder_uintptr_t>(dbStub.GetRefPtr());
824     if (!DetachSessionObject(binderObject)) {
825         DBINDER_LOGE("fail to detach session object");
826         status = false;
827     }
828 
829     if (!DeleteDBinderStub(Str8ToStr16(dbStub->GetServiceName()), dbStub->GetDeviceID())) {
830         DBINDER_LOGE("fail to delete DBinder stub");
831         status = false;
832     }
833 
834     ProcessCallbackProxy(dbStub);
835 
836     return status;
837 }
838 
ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)839 void DBinderService::ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)
840 {
841     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
842 
843     for (auto it = noticeProxy_.begin(); it != noticeProxy_.end();) {
844         if (it->second == dbStub.GetRefPtr()) {
845             IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>((it->first).GetRefPtr());
846             int status = callbackProxy->NoticeServiceDie();
847             if (status != ERR_NONE) {
848                 DBINDER_LOGE("fail to notice service");
849                 // do nothing, Continue to clear subsequent data
850             }
851 
852             sptr<IRemoteObject::DeathRecipient> death = QueryDeathRecipient((it->first));
853             if (death != nullptr) {
854                 // Continue to clear subsequent data
855                 callbackProxy->RemoveDeathRecipient(death);
856             }
857 
858             if (!DetachDeathRecipient((it->first))) {
859                 DBINDER_LOGE("detaching death recipient is failed");
860             }
861 
862             it = noticeProxy_.erase(it);
863         } else {
864             it++;
865         }
866     }
867 }
868 
NoticeServiceDieInner(const std::u16string & serviceName,const std::string & deviceID)869 int32_t DBinderService::NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID)
870 {
871     if (serviceName.empty() || IsDeviceIdIllegal(deviceID)) {
872         DBINDER_LOGE("service name length = %zu, deviceID length = %zu", serviceName.length(), deviceID.length());
873         return DBINDER_SERVICE_INVALID_DATA_ERR;
874     }
875 
876     sptr<DBinderServiceStub> dbStub = FindDBinderStub(serviceName, deviceID);
877     if (dbStub == nullptr) {
878         DBINDER_LOGE("find null stub, do not need notice death");
879         return ERR_NONE;
880     }
881 
882     if (!NoticeCallbackProxy(dbStub)) {
883         DBINDER_LOGE("find null proxy");
884         return DBINDER_SERVICE_NOTICE_DIE_ERR;
885     }
886     return ERR_NONE;
887 }
888 
NoticeServiceDie(const std::u16string & serviceName,const std::string & deviceID)889 int32_t DBinderService::NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID)
890 {
891     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
892     return NoticeServiceDieInner(serviceName, deviceID);
893 }
894 
NoticeDeviceDie(const std::string & deviceID)895 int32_t DBinderService::NoticeDeviceDie(const std::string &deviceID)
896 {
897     if (IsDeviceIdIllegal(deviceID)) {
898         DBINDER_LOGE("deviceID length = %zu", deviceID.length());
899         return DBINDER_SERVICE_INVALID_DATA_ERR;
900     }
901     DBINDER_LOGI("remote device is dead, device = %s", DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
902 
903     if (remoteListener_ == nullptr) {
904         DBINDER_LOGE("remote listener is null");
905         return DBINDER_SERVICE_NOTICE_DIE_ERR;
906     }
907 
908     if (!remoteListener_->CloseDatabusSession(deviceID)) {
909         DBINDER_LOGE("close databus session fail");
910         // do nothing
911     }
912 
913     std::list<std::u16string> serviceNames = FindServicesByDeviceID(deviceID);
914     if (serviceNames.empty()) {
915         DBINDER_LOGE("the device does not have any registered service");
916         return ERR_NONE;
917     }
918 
919     int status = ERR_NONE;
920     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
921 
922     for (auto it = serviceNames.begin(); it != serviceNames.end(); it++) {
923         status += NoticeServiceDieInner((*it), deviceID);
924     }
925 
926     return status;
927 }
928 
FindServicesByDeviceID(const std::string & deviceID)929 std::list<std::u16string> DBinderService::FindServicesByDeviceID(const std::string &deviceID)
930 {
931     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
932     std::list<std::u16string> serviceNames;
933     for (auto it = DBinderStubRegisted_.begin(); it != DBinderStubRegisted_.end(); it++) {
934         if ((*it)->GetDeviceID() == deviceID) {
935             serviceNames.push_back(Str8ToStr16((*it)->GetServiceName()));
936         }
937     }
938 
939     return serviceNames;
940 }
941 
GetRemoteTransType()942 uint32_t DBinderService::GetRemoteTransType()
943 {
944     return IRemoteObject::DATABUS_TYPE;
945 }
946 
ConvertToSecureDeviceID(const std::string & deviceID)947 std::string DBinderService::ConvertToSecureDeviceID(const std::string &deviceID)
948 {
949     if (strlen(deviceID.c_str()) <= ENCRYPT_LENGTH) {
950         return "****";
951     }
952     return deviceID.substr(0, ENCRYPT_LENGTH) + "****" + deviceID.substr(strlen(deviceID.c_str()) - ENCRYPT_LENGTH);
953 }
954 } // namespace OHOS
955