• 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 "dbinder_sa_death_recipient.h"
27 #include "softbus_bus_center.h"
28 
29 namespace OHOS {
30 using namespace Communication;
31 
32 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "DbinderService" };
33 
34 sptr<DBinderService> DBinderService::instance_ = nullptr;
35 bool DBinderService::mainThreadCreated_ = false;
36 std::mutex DBinderService::instanceMutex_;
37 std::shared_ptr<DBinderRemoteListener> DBinderService::remoteListener_ = nullptr;
38 constexpr unsigned int BINDER_MASK = 0xffff;
39 // DBinderServiceStub's reference count in a MakeRemoteBinder call.
40 constexpr int DBINDER_STUB_REF_COUNT = 2;
41 
DBinderService()42 DBinderService::DBinderService()
43 {
44     DBINDER_LOGI(LOG_LABEL, "create dbinder service");
45 }
46 
~DBinderService()47 DBinderService::~DBinderService()
48 {
49     StopRemoteListener();
50 
51     DBinderStubRegisted_.clear();
52     mapDBinderStubRegisters_.clear();
53     mapRemoteBinderObjects_.clear();
54     threadLockInfo_.clear();
55     proxyObject_.clear();
56     sessionObject_.clear();
57     noticeProxy_.clear();
58     deathRecipients_.clear();
59     loadSaReply_.clear();
60     dbinderCallback_ = nullptr;
61     if (StopThreadPool() == false) {
62         DBINDER_LOGE(LOG_LABEL, "failed to stop thread pool");
63     }
64     DBINDER_LOGI(LOG_LABEL, "dbinder service died");
65 }
66 
GetLocalDeviceID()67 std::string DBinderService::GetLocalDeviceID()
68 {
69     std::string pkgName = "DBinderService";
70     NodeBasicInfo nodeBasicInfo;
71     if (GetLocalNodeDeviceInfo(pkgName.c_str(), &nodeBasicInfo) != 0) {
72         DBINDER_LOGE(LOG_LABEL, "Get local node device info failed");
73         return "";
74     }
75     std::string networkId(nodeBasicInfo.networkId);
76     return networkId;
77 }
78 
StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> & callbackImpl)79 bool DBinderService::StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl)
80 {
81     if (mainThreadCreated_) {
82         return ReStartRemoteListener();
83     }
84 
85     bool result = StartRemoteListener();
86     if (!result) {
87         return false;
88     }
89     if (StartThreadPool() == false) {
90         DBINDER_LOGE(LOG_LABEL, "failed to create thread pool");
91         return false;
92     }
93     mainThreadCreated_ = true;
94     dbinderCallback_ = callbackImpl;
95 
96     return true;
97 }
98 
StartRemoteListener()99 bool DBinderService::StartRemoteListener()
100 {
101     if (remoteListener_ != nullptr) {
102         DBINDER_LOGI(LOG_LABEL, "remote listener started");
103         return true;
104     }
105 
106     remoteListener_ = std::make_shared<DBinderRemoteListener>(GetInstance());
107     if (remoteListener_ == nullptr) {
108         DBINDER_LOGE(LOG_LABEL, "failed to create remote listener");
109         return false;
110     }
111 
112     if (remoteListener_->StartListener(remoteListener_) != true) {
113         StopRemoteListener();
114         return false;
115     }
116 
117     DBINDER_LOGI(LOG_LABEL, "start remote listener ok");
118     return true;
119 }
120 
ReStartRemoteListener()121 bool DBinderService::ReStartRemoteListener()
122 {
123     if (remoteListener_ == nullptr) {
124         DBINDER_LOGE(LOG_LABEL, "restart remote listener got null");
125         return false;
126     }
127     if (remoteListener_->StartListener(remoteListener_) != true) {
128         DBINDER_LOGE(LOG_LABEL, "restart dbinder server failed");
129         StopRemoteListener();
130         return false;
131     }
132     return true;
133 }
134 
StopRemoteListener()135 void DBinderService::StopRemoteListener()
136 {
137     if (remoteListener_ != nullptr) {
138         remoteListener_->StopListener();
139         remoteListener_ = nullptr;
140     }
141 }
142 
GetRemoteListener()143 std::shared_ptr<DBinderRemoteListener> DBinderService::GetRemoteListener()
144 {
145     if (remoteListener_ == nullptr && !StartRemoteListener()) {
146         return nullptr;
147     }
148     return remoteListener_;
149 }
150 
GetInstance()151 sptr<DBinderService> DBinderService::GetInstance()
152 {
153     if (instance_ == nullptr) {
154         std::lock_guard<std::mutex> lockGuard(instanceMutex_);
155         if (instance_ == nullptr) {
156             sptr<DBinderService> temp = new DBinderService();
157             instance_ = temp;
158         }
159     }
160     return instance_;
161 }
162 
GetSeqNumber()163 uint32_t DBinderService::GetSeqNumber()
164 {
165     std::lock_guard<std::mutex> lockGuard(instanceMutex_);
166     if (seqNumber_ == std::numeric_limits<uint32_t>::max()) {
167         seqNumber_ = 0;
168     }
169     seqNumber_++;
170     return seqNumber_;
171 }
172 
IsDeviceIdIllegal(const std::string & deviceID)173 bool DBinderService::IsDeviceIdIllegal(const std::string &deviceID)
174 {
175     if (deviceID.empty() || deviceID.length() > DEVICEID_LENGTH) {
176         return true;
177     }
178     return false;
179 }
180 
AddStubByTag(binder_uintptr_t stub)181 binder_uintptr_t DBinderService::AddStubByTag(binder_uintptr_t stub)
182 {
183     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
184 
185     // the same stub needs add stubNum to mapDBinderStubRegisters_, the previous corresponding stubNum will be returned.
186     for (auto iter = mapDBinderStubRegisters_.begin(); iter != mapDBinderStubRegisters_.end(); iter++) {
187         if (iter->second == stub) {
188             return iter->first;
189         }
190     }
191     binder_uintptr_t stubTag = stubTagNum_++;
192     auto result = mapDBinderStubRegisters_.insert(
193         std::pair<binder_uintptr_t, binder_uintptr_t>(stubTag, stub));
194     if (result.second) {
195         return stubTag;
196     } else {
197         return 0;
198     }
199 }
200 
QueryStubPtr(binder_uintptr_t stubTag)201 binder_uintptr_t DBinderService::QueryStubPtr(binder_uintptr_t stubTag)
202 {
203     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
204 
205     auto iter = mapDBinderStubRegisters_.find(stubTag);
206     if (iter != mapDBinderStubRegisters_.end()) {
207         return iter->second;
208     }
209 
210     return 0;
211 }
212 
CheckBinderObject(const sptr<DBinderServiceStub> & stub,binder_uintptr_t stubPtr)213 bool DBinderService::CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t stubPtr)
214 {
215     if (stub == nullptr) {
216         return false;
217     }
218 
219     if (reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()) == stubPtr) {
220         DBINDER_LOGI(LOG_LABEL, "found registered stub");
221         return true;
222     }
223     return false;
224 }
225 
HasDBinderStub(binder_uintptr_t stubPtr)226 bool DBinderService::HasDBinderStub(binder_uintptr_t stubPtr)
227 {
228     auto checkStub = [&stubPtr, this](const sptr<DBinderServiceStub> &stub) {
229         return CheckBinderObject(stub, stubPtr);
230     };
231 
232     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
233     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
234     if (it != DBinderStubRegisted_.end()) {
235         return true;
236     }
237     return false;
238 }
239 
IsSameStubObject(const sptr<DBinderServiceStub> & stub,const std::u16string & service,const std::string & device)240 bool DBinderService::IsSameStubObject(const sptr<DBinderServiceStub> &stub, const std::u16string &service,
241     const std::string &device)
242 {
243     if (stub == nullptr) {
244         return false;
245     }
246     if (IsSameTextStr(stub->GetServiceName(), Str16ToStr8(service)) && IsSameTextStr(stub->GetDeviceID(), device)) {
247         DBINDER_LOGI(LOG_LABEL, "found registered service with name = %{public}s", Str16ToStr8(service).c_str());
248         return true;
249     }
250     return false;
251 }
FindDBinderStub(const std::u16string & service,const std::string & device)252 sptr<DBinderServiceStub> DBinderService::FindDBinderStub(const std::u16string &service, const std::string &device)
253 {
254     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
255         return IsSameStubObject(stub, service, device);
256     };
257 
258     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
259     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
260     if (it == DBinderStubRegisted_.end()) {
261         return nullptr;
262     }
263     return (*it);
264 }
265 
DeleteDBinderStub(const std::u16string & service,const std::string & device)266 bool DBinderService::DeleteDBinderStub(const std::u16string &service, const std::string &device)
267 {
268     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
269         return IsSameStubObject(stub, service, device);
270     };
271 
272     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
273     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
274     if (it == DBinderStubRegisted_.end()) {
275         return false;
276     }
277 
278     for (auto mapIt = mapDBinderStubRegisters_.begin(); mapIt != mapDBinderStubRegisters_.end();) {
279         if (mapIt->second == reinterpret_cast<binder_uintptr_t>((*it).GetRefPtr())) {
280             mapIt = mapDBinderStubRegisters_.erase(mapIt);
281         } else {
282             ++mapIt;
283         }
284     }
285     DBinderStubRegisted_.erase(it);
286     return true;
287 }
288 
FindOrNewDBinderStub(const std::u16string & service,const std::string & device,binder_uintptr_t binderObject)289 sptr<DBinderServiceStub> DBinderService::FindOrNewDBinderStub(const std::u16string &service, const std::string &device,
290     binder_uintptr_t binderObject)
291 {
292     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
293         return IsSameStubObject(stub, service, device);
294     };
295 
296     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
297     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
298     if (it != DBinderStubRegisted_.end()) {
299         return (*it);
300     }
301 
302     sptr<DBinderServiceStub> dBinderServiceStub = new DBinderServiceStub(Str16ToStr8(service), device, binderObject);
303     DBinderStubRegisted_.push_back(dBinderServiceStub);
304     return dBinderServiceStub;
305 }
306 
MakeRemoteBinder(const std::u16string & serviceName,const std::string & deviceID,int32_t binderObject,uint32_t pid,uint32_t uid)307 sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &serviceName,
308     const std::string &deviceID, int32_t binderObject, uint32_t pid, uint32_t uid)
309 {
310     if (IsDeviceIdIllegal(deviceID) || serviceName.length() == 0) {
311         DBINDER_LOGE(LOG_LABEL, "para is wrong device id length = %zu, service name length = %zu", deviceID.length(),
312             serviceName.length());
313         return nullptr;
314     }
315     DBINDER_LOGI(LOG_LABEL, "name = %{public}s, deviceID = %{public}s", Str16ToStr8(serviceName).c_str(),
316         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
317 
318     sptr<DBinderServiceStub> dBinderServiceStub = FindOrNewDBinderStub(serviceName, deviceID,
319         static_cast<binder_uintptr_t>(binderObject));
320     if (dBinderServiceStub == nullptr) {
321         DBINDER_LOGE(LOG_LABEL, "fail to find or new service, service name = %{public}s",
322             Str16ToStr8(serviceName).c_str());
323         return nullptr;
324     }
325 
326     /* if not found dBinderServiceStub, should send msg to toDeviceID
327      * to invoker socket thread and add authentication info for create softbus session
328      */
329     int retryTimes = 0;
330     int32_t ret = -1;
331     do {
332         ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber(), pid, uid);
333         retryTimes++;
334     } while (ret == WAIT_REPLY_TIMEOUT && (retryTimes < RETRY_TIMES));
335 
336     if (ret != DBINDER_OK) {
337         DBINDER_LOGE(LOG_LABEL, "fail to invoke service, service name = %{public}s, device = %{public}s "
338             "DBinderServiceStub refcount = %{public}d",
339             Str16ToStr8(serviceName).c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str(),
340             dBinderServiceStub->GetSptrRefCount());
341         if (dBinderServiceStub->GetSptrRefCount() <= DBINDER_STUB_REF_COUNT) {
342             /* invoke fail, delete dbinder stub info */
343             (void)DeleteDBinderStub(serviceName, deviceID);
344             (void)DetachSessionObject(reinterpret_cast<binder_uintptr_t>(dBinderServiceStub.GetRefPtr()));
345         }
346         return nullptr;
347     }
348 
349     return dBinderServiceStub;
350 }
351 
SendEntryToRemote(const sptr<DBinderServiceStub> stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)352 bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid,
353     uint32_t uid)
354 {
355     const std::string deviceID = stub->GetDeviceID();
356     const std::string localDevID = GetLocalDeviceID();
357     if (IsDeviceIdIllegal(deviceID) || IsDeviceIdIllegal(localDevID)) {
358         DBINDER_LOGE(LOG_LABEL, "wrong device ID");
359         return false;
360     }
361 
362     std::shared_ptr<struct DHandleEntryTxRx> message = std::make_shared<struct DHandleEntryTxRx>();
363     message->head.len            = sizeof(DHandleEntryTxRx);
364     message->head.version        = RPC_TOKENID_SUPPORT_VERSION;
365     message->dBinderCode         = MESSAGE_AS_INVOKER;
366     message->transType           = GetRemoteTransType();
367     message->fromPort            = 0;
368     message->toPort              = 0;
369     message->stubIndex           = static_cast<uint64_t>(std::atoi(stub->GetServiceName().c_str()));
370     message->seqNumber           = seqNumber;
371     message->binderObject        = stub->GetBinderObject();
372     message->stub                = AddStubByTag(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
373     message->deviceIdInfo.tokenId = IPCSkeleton::GetCallingTokenID();
374     message->pid                 = pid;
375     message->uid                 = uid;
376     if (memcpy_s(message->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDevID.data(), localDevID.length()) != 0 ||
377         memcpy_s(message->deviceIdInfo.toDeviceId, DEVICEID_LENGTH, deviceID.data(), deviceID.length()) != 0) {
378         DBINDER_LOGE(LOG_LABEL, "fail to copy memory");
379         return false;
380     }
381     message->deviceIdInfo.fromDeviceId[localDevID.length()] = '\0';
382     message->deviceIdInfo.toDeviceId[deviceID.length()] = '\0';
383     DBINDER_LOGI(LOG_LABEL, "seq = %{public}u stub %{public}llu tokenId %{public}u",
384         message->seqNumber, (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId);
385     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
386     if (remoteListener == nullptr) {
387         DBINDER_LOGE(LOG_LABEL, "remoteListener is null");
388         return false;
389     }
390     bool result = remoteListener->SendDataToRemote(deviceID, message.get());
391     if (result != true) {
392         DBINDER_LOGE(LOG_LABEL, "send to remote dbinderService failed, seq = %{public}u", seqNumber);
393         return false;
394     }
395     return true;
396 }
397 
InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)398 int32_t DBinderService::InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber,
399     uint32_t pid, uint32_t uid)
400 {
401     if (stub == nullptr) {
402         DBINDER_LOGE(LOG_LABEL, "stub is nullptr");
403         return STUB_INVALID;
404     }
405 
406     bool result = SendEntryToRemote(stub, seqNumber, pid, uid);
407     if (!result) {
408         DBINDER_LOGE(LOG_LABEL, "send entry to remote dbinderService fail, seq = %{public}u", seqNumber);
409         return SEND_MESSAGE_FAILED;
410     }
411 
412     /* pend to wait reply */
413     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = std::make_shared<struct ThreadLockInfo>();
414     result = AttachThreadLockInfo(seqNumber, stub->GetDeviceID(), threadLockInfo);
415     if (result != true) {
416         DBINDER_LOGE(LOG_LABEL, "attach lock info fail, seq = %{public}u", seqNumber);
417         return MAKE_THREADLOCK_FAILED;
418     }
419 
420     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
421     if (threadLockInfo->condition.wait_for(lock, std::chrono::seconds(WAIT_FOR_REPLY_MAX_SEC),
422         [&threadLockInfo] { return threadLockInfo->ready; }) == false) {
423         DBINDER_LOGE(LOG_LABEL, "get remote data timeout, seq = %{public}u", seqNumber);
424         DetachThreadLockInfo(seqNumber);
425         threadLockInfo->ready = false;
426         return WAIT_REPLY_TIMEOUT;
427     }
428     /* if can not find session, means invoke failed or nothing in OnRemoteReplyMessage() */
429     auto session = QuerySessionObject(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
430     if (session == nullptr) {
431         DBINDER_LOGE(LOG_LABEL, "client find session is null, seq = %{public}u", seqNumber);
432         return QUERY_REPLY_SESSION_FAILED;
433     }
434     return DBINDER_OK;
435 }
436 
CheckSystemAbilityId(int32_t systemAbilityId)437 bool DBinderService::CheckSystemAbilityId(int32_t systemAbilityId)
438 {
439     return systemAbilityId >= FIRST_SYS_ABILITY_ID && systemAbilityId <= LAST_SYS_ABILITY_ID;
440 }
441 
AllocFreeSocketPort()442 uint16_t DBinderService::AllocFreeSocketPort()
443 {
444     /* alloc port by system */
445     return 0;
446 }
447 
IsSameLoadSaItem(const std::string & srcNetworkId,int32_t systemAbilityId,std::shared_ptr<DHandleEntryTxRx> loadSaItem)448 bool DBinderService::IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId,
449     std::shared_ptr<DHandleEntryTxRx> loadSaItem)
450 {
451     if (static_cast<int32_t>(loadSaItem->stubIndex) == systemAbilityId &&
452         loadSaItem->deviceIdInfo.fromDeviceId == srcNetworkId) {
453         DBINDER_LOGI(LOG_LABEL, "match succeed");
454         return true;
455     }
456     return false;
457 }
458 
PopLoadSaItem(const std::string & srcNetworkId,int32_t systemAbilityId)459 std::shared_ptr<DHandleEntryTxRx> DBinderService::PopLoadSaItem(const std::string& srcNetworkId,
460     int32_t systemAbilityId)
461 {
462     auto checkSaItem = [srcNetworkId, systemAbilityId, this](std::shared_ptr<DHandleEntryTxRx> loadSaItem) {
463         return IsSameLoadSaItem(srcNetworkId, systemAbilityId, loadSaItem);
464     };
465 
466     auto it = std::find_if(loadSaReply_.begin(), loadSaReply_.end(), checkSaItem);
467     if (it == loadSaReply_.end()) {
468         DBINDER_LOGE(LOG_LABEL, "findSaItem failed");
469         return nullptr;
470     }
471     std::shared_ptr<DHandleEntryTxRx> replymsg = (*it);
472     it = loadSaReply_.erase(it);
473     return replymsg;
474 }
475 
LoadSystemAbilityComplete(const std::string & srcNetworkId,int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)476 void DBinderService::LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId,
477     const sptr<IRemoteObject>& remoteObject)
478 {
479     std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
480     while (true) {
481         std::shared_ptr<struct DHandleEntryTxRx> replyMessage = PopLoadSaItem(srcNetworkId, systemAbilityId);
482         if (replyMessage == nullptr) {
483             break;
484         }
485         if (remoteObject == nullptr) {
486             SendMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage);
487             DBINDER_LOGE(LOG_LABEL, "GetSystemAbility from samgr error, saId:%{public}d", systemAbilityId);
488             continue;
489         }
490         binder_uintptr_t binderObject = replyMessage->binderObject;
491         IPCObjectProxy *saProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject.GetRefPtr());
492         if (QueryProxyObject(binderObject) == nullptr) {
493             /* When the stub object dies, you need to delete the corresponding busName information */
494             sptr<IRemoteObject::DeathRecipient> death(new DbinderSaDeathRecipient(binderObject));
495             if (!saProxy->AddDeathRecipient(death)) {
496                 SendMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage);
497                 DBINDER_LOGE(LOG_LABEL, "fail to add death recipient");
498                 continue;
499             }
500             if (!AttachProxyObject(remoteObject, binderObject)) {
501                 DBINDER_LOGW(LOG_LABEL, "attach proxy object is already existed");
502             }
503         }
504         std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId;
505         if (replyMessage->transType != IRemoteObject::DATABUS_TYPE) {
506             SendMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_INVOKE_FAILED, replyMessage);
507             DBINDER_LOGE(LOG_LABEL, "Invalid Message Type");
508         } else {
509             // peer device rpc version == 1, not support thokenId and message->deviceIdInfo.tokenId is random value
510             uint32_t tokenId = (replyMessage->head.version < RPC_TOKENID_SUPPORT_VERSION) ?
511                 0 : replyMessage->deviceIdInfo.tokenId;
512             uint32_t result = OnRemoteInvokerDataBusMessage(saProxy, replyMessage.get(), deviceId,
513                 replyMessage->pid, replyMessage->uid, tokenId);
514             if (result != 0) {
515                 SendMessageToRemote(MESSAGE_AS_REMOTE_ERROR, result, replyMessage);
516                 continue;
517             }
518             SendMessageToRemote(MESSAGE_AS_REPLY, 0, replyMessage);
519         }
520     }
521     DBINDER_LOGI(LOG_LABEL, "LoadSystemAbility complete");
522 }
523 
SendMessageToRemote(uint32_t dBinderCode,uint32_t reason,std::shared_ptr<struct DHandleEntryTxRx> replyMessage)524 void DBinderService::SendMessageToRemote(uint32_t dBinderCode, uint32_t reason,
525     std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
526 {
527     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
528     if (remoteListener == nullptr) {
529         DBINDER_LOGE(LOG_LABEL, "remoteListener is null");
530         return;
531     }
532     replyMessage->dBinderCode = dBinderCode;
533     if (dBinderCode == MESSAGE_AS_REMOTE_ERROR) {
534         replyMessage->transType = reason; // reuse transType send back error code
535     }
536     if (!remoteListener->SendDataToRemote(replyMessage->deviceIdInfo.fromDeviceId, replyMessage.get())) {
537         DBINDER_LOGE(LOG_LABEL, "fail to send data from server DBS to client DBS");
538     }
539 }
540 
OnRemoteInvokerMessage(const struct DHandleEntryTxRx * message)541 bool DBinderService::OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message)
542 {
543     DBINDER_LOGE(LOG_LABEL, "invoke business to create softbus server and spawn thread, "
544         "seq = %{public}u, stub = %{public}llu, tokenId = %{public}u",
545         message->seqNumber, (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId);
546     std::shared_ptr<struct DHandleEntryTxRx> replyMessage = std::make_shared<struct DHandleEntryTxRx>();
547     if (memcpy_s(replyMessage.get(), sizeof(DHandleEntryTxRx), message, sizeof(DHandleEntryTxRx)) != 0) {
548         DBINDER_LOGE(LOG_LABEL, "fail to copy memory of DHandleEntryTxRx");
549         return false;
550     }
551 
552     std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
553     bool isSaAvailable = dbinderCallback_->LoadSystemAbilityFromRemote(replyMessage->deviceIdInfo.fromDeviceId,
554         static_cast<int32_t>(replyMessage->stubIndex));
555     if (!isSaAvailable) {
556         DBINDER_LOGE(LOG_LABEL, "fail to call the system ability");
557         return false;
558     }
559     loadSaReply_.push_back(replyMessage);
560     return true;
561 }
562 
GetDatabusNameByProxy(IPCObjectProxy * proxy)563 std::string DBinderService::GetDatabusNameByProxy(IPCObjectProxy *proxy)
564 {
565     if (proxy == nullptr) {
566         DBINDER_LOGE(LOG_LABEL, "proxy can not be null");
567         return "";
568     }
569     std::string sessionName = proxy->GetSessionName();
570     if (sessionName.empty()) {
571         DBINDER_LOGE(LOG_LABEL, "grand session name failed");
572         return "";
573     }
574     return sessionName;
575 }
576 
CreateDatabusName(int uid,int pid)577 std::string DBinderService::CreateDatabusName(int uid, int pid)
578 {
579     std::shared_ptr<ISessionService> softbusManager = ISessionService::GetInstance();
580     if (softbusManager == nullptr) {
581         DBINDER_LOGE(LOG_LABEL, "fail to get softbus service");
582         return "";
583     }
584 
585     std::string sessionName = "DBinder" + std::to_string(uid) + std::string("_") + std::to_string(pid);
586     if (softbusManager->GrantPermission(uid, pid, sessionName) != ERR_NONE) {
587         DBINDER_LOGE(LOG_LABEL, "fail to Grant Permission softbus name");
588         return "";
589     }
590 
591     return sessionName;
592 }
593 
OnRemoteInvokerDataBusMessage(IPCObjectProxy * proxy,struct DHandleEntryTxRx * replyMessage,std::string & remoteDeviceId,int pid,int uid,uint32_t tokenId)594 uint32_t DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage,
595     std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId)
596 {
597     if (IsDeviceIdIllegal(remoteDeviceId)) {
598         DBINDER_LOGE(LOG_LABEL, "remote device id is error");
599         return DEVICEID_INVALID;
600     }
601     std::string sessionName = GetDatabusNameByProxy(proxy);
602     if (sessionName.empty()) {
603         DBINDER_LOGE(LOG_LABEL, "get bus name fail");
604         return SESSION_NAME_NOT_FOUND;
605     }
606 
607     MessageParcel data;
608     MessageParcel reply;
609     if (!data.WriteUint16(IRemoteObject::DATABUS_TYPE) || !data.WriteString(GetLocalDeviceID()) ||
610         !data.WriteUint32(pid) || !data.WriteUint32(uid) || !data.WriteString(remoteDeviceId) ||
611         !data.WriteString(sessionName) || !data.WriteUint32(tokenId)) {
612         DBINDER_LOGE(LOG_LABEL, "write to parcel fail");
613         return WRITE_PARCEL_FAILED;
614     }
615     int err = proxy->InvokeListenThread(data, reply);
616     if (err != ERR_NONE) {
617         DBINDER_LOGE(LOG_LABEL, "start service listen error = %{public}d", err);
618         return INVOKE_STUB_THREAD_FAILED;
619     }
620     uint64_t stubIndex = reply.ReadUint64();
621     std::string serverSessionName = reply.ReadString();
622     std::string deviceId = reply.ReadString();
623     uint32_t selfTokenId = reply.ReadUint32();
624     if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) {
625         DBINDER_LOGE(LOG_LABEL, "stubindex or session name invalid, deviceId = %{public}s",
626             DBinderService::ConvertToSecureDeviceID(deviceId).c_str());
627         return SESSION_NAME_INVALID;
628     }
629     replyMessage->dBinderCode = MESSAGE_AS_REPLY;
630     if (replyMessage->head.version >= RPC_TOKENID_SUPPORT_VERSION) {
631         replyMessage->dBinderCode = MESSAGE_AS_REPLY_TOKENID;
632     }
633     replyMessage->head.version = RPC_TOKENID_SUPPORT_VERSION;
634     replyMessage->stubIndex = stubIndex;
635     replyMessage->serviceNameLength = serverSessionName.length();
636     replyMessage->deviceIdInfo.tokenId = selfTokenId;
637     if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(),
638         replyMessage->serviceNameLength) != 0) {
639         DBINDER_LOGE(LOG_LABEL, "fail to copy memory");
640         return SESSION_NAME_INVALID;
641     }
642     replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
643     return 0;
644 }
645 
GetRegisterService(binder_uintptr_t binderObject)646 std::u16string DBinderService::GetRegisterService(binder_uintptr_t binderObject)
647 {
648     DBINDER_LOGI(LOG_LABEL, "get service binderObject");
649     std::shared_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
650     for (auto it = mapRemoteBinderObjects_.begin(); it != mapRemoteBinderObjects_.end(); it++) {
651         if (it->second == binderObject) {
652             return it->first;
653         }
654     }
655     return std::u16string();
656 }
657 
RegisterRemoteProxy(std::u16string serviceName,sptr<IRemoteObject> binderObject)658 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject)
659 {
660     DBINDER_LOGI(LOG_LABEL, "register remote proxy, service name = %{public}s", Str16ToStr8(serviceName).c_str());
661 
662     if (serviceName.length() == 0 || binderObject == nullptr) {
663         DBINDER_LOGE(LOG_LABEL, "serviceName.length() = %{public}zu", serviceName.length());
664         return false;
665     }
666 
667     binder_uintptr_t binder = (binder_uintptr_t)binderObject.GetRefPtr();
668     return RegisterRemoteProxyInner(serviceName, binder);
669 }
670 
RegisterRemoteProxy(std::u16string serviceName,int32_t systemAbilityId)671 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId)
672 {
673     DBINDER_LOGI(LOG_LABEL, "register remote proxy, service name = %{public}s", Str16ToStr8(serviceName).c_str());
674 
675     if (serviceName.length() == 0 || systemAbilityId <= 0) {
676         DBINDER_LOGE(LOG_LABEL, "serviceName.length() = %zu", serviceName.length());
677         return false;
678     }
679 
680     binder_uintptr_t binder = (binder_uintptr_t)systemAbilityId;
681     return RegisterRemoteProxyInner(serviceName, binder);
682 }
683 
RegisterRemoteProxyInner(std::u16string serviceName,binder_uintptr_t binder)684 bool DBinderService::RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder)
685 {
686     std::unique_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
687     // clear historical remnants, Don't care if it succeeds
688     (void)mapRemoteBinderObjects_.erase(serviceName);
689     auto result = mapRemoteBinderObjects_.insert(std::pair<std::u16string, binder_uintptr_t>(serviceName, binder));
690     return result.second;
691 }
692 
StartThreadPool()693 bool DBinderService::StartThreadPool()
694 {
695     std::lock_guard<std::mutex> lock(threadPoolMutex_);
696     if (threadPoolStarted_) {
697         return true;
698     }
699     if (threadPool_ == nullptr) {
700         threadPool_ = std::make_unique<ThreadPool>("DBinderRemoteListener");
701     } else {
702         return false;
703     }
704     if (threadPool_->Start(threadPoolNumber_) != ERR_OK) {
705         threadPool_.reset();
706         return false;
707     }
708     threadPool_->SetMaxTaskNum(threadPoolNumber_);
709     threadPoolStarted_ = true;
710     return true;
711 }
712 
StopThreadPool()713 bool DBinderService::StopThreadPool()
714 {
715     std::lock_guard<std::mutex> lock(threadPoolMutex_);
716     if (threadPoolStarted_) {
717         threadPoolStarted_ = false;
718         threadPool_->Stop();
719         threadPool_.reset();
720     }
721     return true;
722 }
723 
AddAsynTask(const ThreadPool::Task & f)724 bool DBinderService::AddAsynTask(const ThreadPool::Task &f)
725 {
726     if (threadPoolStarted_ && threadPool_ != nullptr) {
727         threadPool_->AddTask(f);
728         return true;
729     } else {
730         DBINDER_LOGE(LOG_LABEL, "failed to post async task");
731         return false;
732     }
733 }
734 
AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)735 void DBinderService::AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)
736 {
737     auto task = std::bind(&DBinderService::OnRemoteMessageTask, this, message);
738     AddAsynTask(task);
739 }
740 
OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)741 bool DBinderService::OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)
742 {
743     if (message == nullptr) {
744         DBINDER_LOGE(LOG_LABEL, "message is null");
745         return false;
746     }
747 
748     bool result = false;
749     switch (message->dBinderCode) {
750         case MESSAGE_AS_INVOKER: {
751             result = OnRemoteInvokerMessage(message.get());
752             break;
753         }
754         case MESSAGE_AS_REPLY:
755         case MESSAGE_AS_REPLY_TOKENID: {
756             result = OnRemoteReplyMessage(message.get());
757             break;
758         }
759         case MESSAGE_AS_REMOTE_ERROR: {
760             result = OnRemoteErrorMessage(message.get());
761             break;
762         }
763         default: {
764             DBINDER_LOGE(LOG_LABEL, "DbinderCode is not support, code =%{public}u", message->dBinderCode);
765             result = false;
766             break;
767         }
768     }
769     return result;
770 }
771 
ProcessOnSessionClosed(std::shared_ptr<Session> session)772 bool DBinderService::ProcessOnSessionClosed(std::shared_ptr<Session> session)
773 {
774     if (session == nullptr) {
775         DBINDER_LOGE(LOG_LABEL, "ERROR!Session is nullptr!");
776         return false;
777     }
778     std::lock_guard<std::mutex> lock(threadLockMutex_);
779     for (auto it = threadLockInfo_.begin(); it != threadLockInfo_.end();) {
780         if (it->second->networkId != session->GetPeerDeviceId()) {
781             continue;
782         }
783         std::unique_lock<std::mutex> lock(it->second->mutex);
784         it->second->ready = true;
785         it->second->condition.notify_all();
786         it = threadLockInfo_.erase(it);
787     }
788     return true;
789 }
790 
OnRemoteErrorMessage(const struct DHandleEntryTxRx * replyMessage)791 bool DBinderService::OnRemoteErrorMessage(const struct DHandleEntryTxRx *replyMessage)
792 {
793     DBINDER_LOGI(LOG_LABEL, "invoke remote stub = %{public}d error, type = %{public}u, seq = %{public}u",
794         static_cast<int32_t>(replyMessage->stubIndex), replyMessage->transType, replyMessage->seqNumber);
795     WakeupThreadByStub(replyMessage->seqNumber);
796     DetachThreadLockInfo(replyMessage->seqNumber);
797     return true;
798 }
799 
OnRemoteReplyMessage(const struct DHandleEntryTxRx * replyMessage)800 bool DBinderService::OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage)
801 {
802     DBINDER_LOGI(LOG_LABEL, "seq = %{public}u, stub = %{public}llu, tokenId = %{public}u, dBinderCode = %{public}u",
803         replyMessage->seqNumber, (replyMessage->stub & BINDER_MASK), replyMessage->deviceIdInfo.tokenId,
804         replyMessage->dBinderCode);
805     MakeSessionByReplyMessage(replyMessage);
806     WakeupThreadByStub(replyMessage->seqNumber);
807     DetachThreadLockInfo(replyMessage->seqNumber);
808     return true;
809 }
810 
IsSameSession(std::shared_ptr<struct SessionInfo> oldSession,std::shared_ptr<struct SessionInfo> newSession)811 bool DBinderService::IsSameSession(std::shared_ptr<struct SessionInfo> oldSession,
812     std::shared_ptr<struct SessionInfo> newSession)
813 {
814     if ((oldSession->stubIndex != newSession->stubIndex) || (oldSession->toPort != newSession->toPort)
815         || (oldSession->fromPort != newSession->fromPort) || (oldSession->type != newSession->type)
816         || (oldSession->serviceName != newSession->serviceName)) {
817         return false;
818     }
819     if (strncmp(oldSession->deviceIdInfo.fromDeviceId, newSession->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH) != 0
820         || strncmp(oldSession->deviceIdInfo.toDeviceId, newSession->deviceIdInfo.toDeviceId, DEVICEID_LENGTH) != 0) {
821         return false;
822     }
823 
824     return true;
825 }
826 
MakeSessionByReplyMessage(const struct DHandleEntryTxRx * replyMessage)827 void DBinderService::MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage)
828 {
829     if (HasDBinderStub(QueryStubPtr(replyMessage->stub)) == false) {
830         DBINDER_LOGE(LOG_LABEL, "invalid stub object");
831         return;
832     }
833 
834     std::shared_ptr<struct SessionInfo> session = std::make_shared<struct SessionInfo>();
835     if (session == nullptr) {
836         DBINDER_LOGE(LOG_LABEL, "new SessionInfo fail");
837         return;
838     }
839 
840     if (memcpy_s(&session->deviceIdInfo, sizeof(struct DeviceIdInfo), &replyMessage->deviceIdInfo,
841         sizeof(struct DeviceIdInfo)) != 0) {
842         DBINDER_LOGE(LOG_LABEL, "fail to copy memory");
843         return;
844     }
845     // remote device NOT support tokenId, clear random value
846     if (replyMessage->dBinderCode == MESSAGE_AS_REPLY) {
847         session->deviceIdInfo.tokenId = 0;
848     }
849     DBINDER_LOGI(LOG_LABEL, "stubIndex: %{public}d, tokenId: %{public}u",
850         static_cast<int32_t>(replyMessage->stubIndex), session->deviceIdInfo.tokenId);
851     session->seqNumber   = replyMessage->seqNumber;
852     session->socketFd    = 0;
853     session->stubIndex   = replyMessage->stubIndex;
854     session->toPort      = replyMessage->toPort;
855     session->fromPort    = replyMessage->fromPort;
856     session->type        = replyMessage->transType;
857     session->serviceName = replyMessage->serviceName;
858 
859     if (session->stubIndex == 0) {
860         DBINDER_LOGE(LOG_LABEL, "get stub index == 0, it is invalid");
861         return;
862     }
863     // check whether need to update session
864     std::shared_ptr<struct SessionInfo> oldSession = QuerySessionObject(QueryStubPtr(replyMessage->stub));
865     if (oldSession != nullptr) {
866         if (IsSameSession(oldSession, session) == true) {
867             DBINDER_LOGI(LOG_LABEL, "invoker remote session already, do nothing");
868             return;
869         } else {
870             // ignore seqNumber overflow here, greater seqNumber means later request
871             if (oldSession->seqNumber < session->seqNumber) {
872                 // remote old session
873                 if (!DetachSessionObject(QueryStubPtr(replyMessage->stub))) {
874                     DBINDER_LOGE(LOG_LABEL, "failed to detach session object");
875                 }
876             } else {
877                 // do nothing, use old session, discard session got this time
878                 // in this case, old session is requested later, but it comes back earlier
879             }
880         }
881     }
882 
883     if (!AttachSessionObject(session, QueryStubPtr(replyMessage->stub))) {
884         DBINDER_LOGE(LOG_LABEL, "attach SessionInfo fail");
885         return;
886     }
887 }
888 
WakeupThreadByStub(uint32_t seqNumber)889 void DBinderService::WakeupThreadByStub(uint32_t seqNumber)
890 {
891     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = QueryThreadLockInfo(seqNumber);
892     if (threadLockInfo == nullptr) {
893         DBINDER_LOGE(LOG_LABEL, "threadLockInfo is not exist");
894         return;
895     }
896     /* Wake up the client processing thread */
897     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
898     threadLockInfo->ready = true;
899     threadLockInfo->condition.notify_all();
900 }
901 
DetachThreadLockInfo(uint32_t seqNumber)902 void DBinderService::DetachThreadLockInfo(uint32_t seqNumber)
903 {
904     std::lock_guard<std::mutex> lock(threadLockMutex_);
905     threadLockInfo_.erase(seqNumber);
906 }
907 
AttachThreadLockInfo(uint32_t seqNumber,const std::string & networkId,std::shared_ptr<struct ThreadLockInfo> object)908 bool DBinderService::AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId,
909     std::shared_ptr<struct ThreadLockInfo> object)
910 {
911     std::lock_guard<std::mutex> lock(threadLockMutex_);
912     object->networkId = networkId;
913     auto result =
914         threadLockInfo_.insert(std::pair<uint32_t, std::shared_ptr<struct ThreadLockInfo>>(seqNumber, object));
915     return result.second;
916 }
917 
QueryThreadLockInfo(uint32_t seqNumber)918 std::shared_ptr<struct ThreadLockInfo> DBinderService::QueryThreadLockInfo(uint32_t seqNumber)
919 {
920     std::lock_guard<std::mutex> lock(threadLockMutex_);
921 
922     auto it = threadLockInfo_.find(seqNumber);
923     if (it != threadLockInfo_.end()) {
924         return it->second;
925     }
926     return nullptr;
927 }
928 
DetachProxyObject(binder_uintptr_t binderObject)929 bool DBinderService::DetachProxyObject(binder_uintptr_t binderObject)
930 {
931     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
932 
933     return (proxyObject_.erase(binderObject) > 0);
934 }
935 
AttachProxyObject(sptr<IRemoteObject> object,binder_uintptr_t binderObject)936 bool DBinderService::AttachProxyObject(sptr<IRemoteObject> object, binder_uintptr_t binderObject)
937 {
938     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
939 
940     auto result = proxyObject_.insert(std::pair<int, sptr<IRemoteObject>>(binderObject, object));
941     return result.second;
942 }
943 
QueryProxyObject(binder_uintptr_t binderObject)944 sptr<IRemoteObject> DBinderService::QueryProxyObject(binder_uintptr_t binderObject)
945 {
946     std::shared_lock<std::shared_mutex> lock(proxyMutex_);
947 
948     auto it = proxyObject_.find(binderObject);
949     if (it != proxyObject_.end()) {
950         return it->second;
951     }
952     return nullptr;
953 }
954 
DetachSessionObject(binder_uintptr_t stub)955 bool DBinderService::DetachSessionObject(binder_uintptr_t stub)
956 {
957     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
958     return (sessionObject_.erase(stub) > 0);
959 }
960 
AttachSessionObject(std::shared_ptr<struct SessionInfo> object,binder_uintptr_t stub)961 bool DBinderService::AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub)
962 {
963     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
964 
965     auto ret = sessionObject_.insert(std::pair<binder_uintptr_t, std::shared_ptr<struct SessionInfo>>(stub, object));
966     return ret.second;
967 }
968 
QuerySessionObject(binder_uintptr_t stub)969 std::shared_ptr<struct SessionInfo> DBinderService::QuerySessionObject(binder_uintptr_t stub)
970 {
971     std::shared_lock<std::shared_mutex> lock(sessionMutex_);
972 
973     auto it = sessionObject_.find(stub);
974     if (it != sessionObject_.end()) {
975         return it->second;
976     }
977     return nullptr;
978 }
979 
DetachDeathRecipient(sptr<IRemoteObject> object)980 bool DBinderService::DetachDeathRecipient(sptr<IRemoteObject> object)
981 {
982     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
983 
984     return (deathRecipients_.erase(object) > 0);
985 }
986 
AttachDeathRecipient(sptr<IRemoteObject> object,sptr<IRemoteObject::DeathRecipient> deathRecipient)987 bool DBinderService::AttachDeathRecipient(sptr<IRemoteObject> object,
988     sptr<IRemoteObject::DeathRecipient> deathRecipient)
989 {
990     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
991 
992     auto ret = deathRecipients_.insert(
993         std::pair<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>>(object, deathRecipient));
994 
995     return ret.second;
996 }
997 
QueryDeathRecipient(sptr<IRemoteObject> object)998 sptr<IRemoteObject::DeathRecipient> DBinderService::QueryDeathRecipient(sptr<IRemoteObject> object)
999 {
1000     std::shared_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
1001 
1002     auto it = deathRecipients_.find(object);
1003     if (it != deathRecipients_.end()) {
1004         return it->second;
1005     }
1006 
1007     return nullptr;
1008 }
1009 
1010 
DetachCallbackProxy(sptr<IRemoteObject> object)1011 bool DBinderService::DetachCallbackProxy(sptr<IRemoteObject> object)
1012 {
1013     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1014 
1015     return (noticeProxy_.erase(object) > 0);
1016 }
1017 
AttachCallbackProxy(sptr<IRemoteObject> object,DBinderServiceStub * dbStub)1018 bool DBinderService::AttachCallbackProxy(sptr<IRemoteObject> object, DBinderServiceStub *dbStub)
1019 {
1020     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1021 
1022     auto result = noticeProxy_.insert(std::pair<sptr<IRemoteObject>, DBinderServiceStub *>(object, dbStub));
1023 
1024     return result.second;
1025 }
1026 
NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)1027 bool DBinderService::NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)
1028 {
1029     DBINDER_LOGI(LOG_LABEL, "%{public}s: enter, service:%{public}s devicId:%{public}s",
1030         __func__, dbStub->GetServiceName().c_str(),
1031         DBinderService::ConvertToSecureDeviceID(dbStub->GetDeviceID()).c_str());
1032     bool status = true;
1033     const binder_uintptr_t binderObject = reinterpret_cast<binder_uintptr_t>(dbStub.GetRefPtr());
1034     if (!DetachSessionObject(binderObject)) {
1035         DBINDER_LOGE(LOG_LABEL, "fail to detach session object");
1036         status = false;
1037     }
1038 
1039     if (!DeleteDBinderStub(Str8ToStr16(dbStub->GetServiceName()), dbStub->GetDeviceID())) {
1040         DBINDER_LOGE(LOG_LABEL, "fail to delete DBinder stub");
1041         status = false;
1042     }
1043 
1044     ProcessCallbackProxy(dbStub);
1045 
1046     return status;
1047 }
1048 
ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)1049 void DBinderService::ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)
1050 {
1051     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1052 
1053     for (auto it = noticeProxy_.begin(); it != noticeProxy_.end();) {
1054         if (it->second == dbStub.GetRefPtr()) {
1055             IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>((it->first).GetRefPtr());
1056             int status = callbackProxy->NoticeServiceDie();
1057             if (status != ERR_NONE) {
1058                 DBINDER_LOGE(LOG_LABEL, "fail to notice service");
1059                 // do nothing, Continue to clear subsequent data
1060             }
1061 
1062             sptr<IRemoteObject::DeathRecipient> death = QueryDeathRecipient((it->first));
1063             if (death != nullptr) {
1064                 // Continue to clear subsequent data
1065                 callbackProxy->RemoveDeathRecipient(death);
1066             }
1067 
1068             if (!DetachDeathRecipient((it->first))) {
1069                 DBINDER_LOGE(LOG_LABEL, "detaching death recipient is failed");
1070             }
1071 
1072             it = noticeProxy_.erase(it);
1073         } else {
1074             it++;
1075         }
1076     }
1077 }
1078 
NoticeServiceDieInner(const std::u16string & serviceName,const std::string & deviceID)1079 int32_t DBinderService::NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID)
1080 {
1081     if (serviceName.empty() || IsDeviceIdIllegal(deviceID)) {
1082         DBINDER_LOGE(LOG_LABEL, "service name length = %{public}zu, deviceID length = %{public}zu",
1083             serviceName.length(), deviceID.length());
1084         return DBINDER_SERVICE_INVALID_DATA_ERR;
1085     }
1086 
1087     DBINDER_LOGI(LOG_LABEL, "%{public}s: service:%{public}s devicId:%{public}s",
1088         __func__, Str16ToStr8(serviceName).c_str(),
1089         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
1090     sptr<DBinderServiceStub> dbStub = FindDBinderStub(serviceName, deviceID);
1091     if (dbStub == nullptr) {
1092         DBINDER_LOGE(LOG_LABEL, "find null stub, do not need notice death");
1093         return ERR_NONE;
1094     }
1095 
1096     if (!NoticeCallbackProxy(dbStub)) {
1097         DBINDER_LOGE(LOG_LABEL, "find null proxy");
1098         return DBINDER_SERVICE_NOTICE_DIE_ERR;
1099     }
1100     return ERR_NONE;
1101 }
1102 
NoticeServiceDie(const std::u16string & serviceName,const std::string & deviceID)1103 int32_t DBinderService::NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID)
1104 {
1105     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
1106     return NoticeServiceDieInner(serviceName, deviceID);
1107 }
1108 
NoticeDeviceDie(const std::string & deviceID)1109 int32_t DBinderService::NoticeDeviceDie(const std::string &deviceID)
1110 {
1111     if (IsDeviceIdIllegal(deviceID)) {
1112         DBINDER_LOGE(LOG_LABEL, "deviceID length = %zu", deviceID.length());
1113         return DBINDER_SERVICE_INVALID_DATA_ERR;
1114     }
1115     DBINDER_LOGI(LOG_LABEL, "remote device = %{public}s is dead",
1116         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
1117 
1118     if (remoteListener_ == nullptr) {
1119         DBINDER_LOGE(LOG_LABEL, "remote listener is null");
1120         return DBINDER_SERVICE_NOTICE_DIE_ERR;
1121     }
1122 
1123     if (!remoteListener_->CloseDatabusSession(deviceID)) {
1124         DBINDER_LOGE(LOG_LABEL, "close databus session fail");
1125         // do nothing
1126     }
1127 
1128     std::list<std::u16string> serviceNames = FindServicesByDeviceID(deviceID);
1129     if (serviceNames.empty()) {
1130         DBINDER_LOGE(LOG_LABEL, "the device does not have any registered service");
1131         return ERR_NONE;
1132     }
1133 
1134     int status = ERR_NONE;
1135     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
1136 
1137     for (auto it = serviceNames.begin(); it != serviceNames.end(); it++) {
1138         status += NoticeServiceDieInner((*it), deviceID);
1139     }
1140 
1141     return status;
1142 }
1143 
FindServicesByDeviceID(const std::string & deviceID)1144 std::list<std::u16string> DBinderService::FindServicesByDeviceID(const std::string &deviceID)
1145 {
1146     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
1147     std::list<std::u16string> serviceNames;
1148     for (auto it = DBinderStubRegisted_.begin(); it != DBinderStubRegisted_.end(); it++) {
1149         if ((*it)->GetDeviceID() == deviceID) {
1150             serviceNames.push_back(Str8ToStr16((*it)->GetServiceName()));
1151         }
1152     }
1153 
1154     return serviceNames;
1155 }
1156 
GetRemoteTransType()1157 uint32_t DBinderService::GetRemoteTransType()
1158 {
1159     return IRemoteObject::DATABUS_TYPE;
1160 }
1161 
ConvertToSecureDeviceID(const std::string & deviceID)1162 std::string DBinderService::ConvertToSecureDeviceID(const std::string &deviceID)
1163 {
1164     if (strlen(deviceID.c_str()) <= ENCRYPT_LENGTH) {
1165         return "****";
1166     }
1167     return deviceID.substr(0, ENCRYPT_LENGTH) + "****" + deviceID.substr(strlen(deviceID.c_str()) - ENCRYPT_LENGTH);
1168 }
1169 } // namespace OHOS
1170