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