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