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 #ifdef LOG_TAG
16 #undef LOG_TAG
17 #endif
18 #define LOG_TAG "SoftBusAdapter"
19
20 #include "softbus_adapter.h"
21
22 #include "accesstoken_kit.h"
23 #include "account/account_delegate.h"
24 #include "communication/connect_manager.h"
25 #include "communicator_context.h"
26 #include "data_level.h"
27 #include "device_manager_adapter.h"
28 #include "log_print.h"
29 #include "metadata/appid_meta_data.h"
30 #include "metadata/meta_data_manager.h"
31 #include "metadata/store_meta_data.h"
32 #include "softbus_error_code.h"
33 #include "utils/anonymous.h"
34
35 namespace OHOS {
36 namespace AppDistributedKv {
37 using namespace std;
38 using namespace OHOS::DistributedKv;
39 using namespace OHOS::DistributedData;
40 using namespace OHOS::Security::AccessToken;
41
42 static constexpr const char *DEFAULT_USER = "default";
43 static constexpr const char *SYSTEM_USER = "0";
44 static constexpr const char *PKG_NAME = "distributeddata-default";
45 static constexpr uint32_t DEFAULT_MTU_SIZE = 4096 * 1024u;
46 static constexpr uint32_t DEFAULT_TIMEOUT = 30 * 1000;
47 static constexpr uint32_t QOS_COUNT = 3;
48 static constexpr QosTV Qos[QOS_COUNT] = { { .qos = QOS_TYPE_MIN_BW, .value = 64 * 1024 },
49 { .qos = QOS_TYPE_MAX_LATENCY, .value = 15000 }, { .qos = QOS_TYPE_MIN_LATENCY, .value = 1600 } };
50
51 class AppDataListenerWrap {
52 public:
53 static void SetDataHandler(SoftBusAdapter *handler);
54
55 static void OnClientShutdown(int32_t socket, ShutdownReason reason);
56 static void OnClientBytesReceived(int32_t socket, const void *data, uint32_t dataLen);
57 static void OnClientSocketChanged(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount);
58
59 static void OnServerBind(int32_t socket, PeerSocketInfo info);
60 static void OnServerShutdown(int32_t socket, ShutdownReason reason);
61 static void OnServerBytesReceived(int32_t socket, const void *data, uint32_t dataLen);
62 static bool OnServerAccessCheck(int32_t socket, PeerSocketInfo info, SocketAccessInfo *peerInfo,
63 SocketAccessInfo *localInfo);
64
65 private:
66 // notify all listeners when received message
67 static void NotifyDataListeners(const uint8_t *data, const int size, const std::string &deviceId,
68 const PipeInfo &pipeInfo);
69 static std::string GetPipeId(const std::string &name);
70 static std::pair<bool, StoreMetaData> LoadMetaData(const std::string &bundleName, const std::string &storeId,
71 int32_t userId);
72
73 static SoftBusAdapter *softBusAdapter_;
74 };
75
76 SoftBusAdapter *AppDataListenerWrap::softBusAdapter_;
77 std::shared_ptr<SoftBusAdapter> SoftBusAdapter::instance_;
78
79 namespace {
OnDataLevelChanged(const char * networkId,const DataLevel dataLevel)80 void OnDataLevelChanged(const char* networkId, const DataLevel dataLevel)
81 {
82 if (networkId == nullptr) {
83 return;
84 }
85 LevelInfo level = {
86 .dynamic = dataLevel.dynamicLevel,
87 .statics = dataLevel.staticLevel,
88 .switches = dataLevel.switchLevel,
89 .switchesLen = dataLevel.switchLength,
90 };
91 auto uuid = DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(networkId);
92 SoftBusAdapter::GetInstance()->OnBroadcast({ uuid }, std::move(level));
93 }
94
95 IDataLevelCb g_callback = {
96 .onDataLevelChanged = OnDataLevelChanged,
97 };
98 } // namespace
99
SoftBusAdapter()100 SoftBusAdapter::SoftBusAdapter()
101 {
102 ZLOGI("begin");
103 AppDataListenerWrap::SetDataHandler(this);
104
105 clientListener_.OnShutdown = AppDataListenerWrap::OnClientShutdown;
106 clientListener_.OnBytes = AppDataListenerWrap::OnClientBytesReceived;
107 clientListener_.OnMessage = AppDataListenerWrap::OnClientBytesReceived;
108 clientListener_.OnQos = AppDataListenerWrap::OnClientSocketChanged;
109
110 serverListener_.OnBind = AppDataListenerWrap::OnServerBind;
111 serverListener_.OnShutdown = AppDataListenerWrap::OnServerShutdown;
112 serverListener_.OnBytes = AppDataListenerWrap::OnServerBytesReceived;
113 serverListener_.OnMessage = AppDataListenerWrap::OnServerBytesReceived;
114 serverListener_.OnNegotiate2 = AppDataListenerWrap::OnServerAccessCheck;
115
116 CommunicatorContext::GetInstance().SetSessionListener([this](const std::string &deviceId) {
117 StartCloseSessionTask(deviceId);
118 });
119
120 ConnectManager::GetInstance()->RegisterCloseSessionTask([this](const std::string &networkId) {
121 return CloseSession(networkId);
122 });
123 ConnectManager::GetInstance()->RegisterSessionCloseListener("CommunicatorContext",
124 [](const std::string &networkId) {
125 auto uuid = DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(networkId);
126 CommunicatorContext::GetInstance().NotifySessionClose(uuid);
127 });
128 ConnectManager::GetInstance()->OnStart();
129 }
130
~SoftBusAdapter()131 SoftBusAdapter::~SoftBusAdapter()
132 {
133 ZLOGI("begin");
134 if (onBroadcast_) {
135 UnregDataLevelChangeCb(PKG_NAME);
136 }
137 connects_.Clear();
138 ConnectManager::GetInstance()->OnDestory();
139 }
140
GetInstance()141 std::shared_ptr<SoftBusAdapter> SoftBusAdapter::GetInstance()
142 {
143 static std::once_flag onceFlag;
144 std::call_once(onceFlag, [&] {
145 instance_ = std::make_shared<SoftBusAdapter>();
146 });
147 return instance_;
148 }
149
StartWatchDataChange(const AppDataChangeListener * observer,const PipeInfo & pipeInfo)150 Status SoftBusAdapter::StartWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo)
151 {
152 ZLOGD("begin");
153 if (observer == nullptr) {
154 return Status::INVALID_ARGUMENT;
155 }
156
157 auto ret = dataChangeListeners_.Insert(pipeInfo.pipeId, observer);
158 if (!ret) {
159 ZLOGW("Add listener error or repeated adding.");
160 return Status::ERROR;
161 }
162
163 return Status::SUCCESS;
164 }
165
StopWatchDataChange(const AppDataChangeListener * observer,const PipeInfo & pipeInfo)166 Status SoftBusAdapter::StopWatchDataChange(__attribute__((unused)) const AppDataChangeListener *observer,
167 const PipeInfo &pipeInfo)
168 {
169 ZLOGD("begin");
170 if (dataChangeListeners_.Erase(pipeInfo.pipeId) != 0) {
171 return Status::SUCCESS;
172 }
173 ZLOGW("stop data observer error, pipeInfo:%{public}s", pipeInfo.pipeId.c_str());
174 return Status::ERROR;
175 }
176
GetExpireTime(std::shared_ptr<SoftBusClient> & conn)177 void SoftBusAdapter::GetExpireTime(std::shared_ptr<SoftBusClient> &conn)
178 {
179 Time now = std::chrono::steady_clock::now();
180 auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now;
181 lock_guard<decltype(taskMutex_)> lock(taskMutex_);
182 if (taskId_ != ExecutorPool::INVALID_TASK_ID && expireTime < next_) {
183 taskId_ = CommunicatorContext::GetInstance().GetThreadPool()->Reset(taskId_, expireTime - now);
184 next_ = expireTime;
185 }
186 }
187
SendData(const PipeInfo & pipeInfo,const DeviceId & deviceId,const DataInfo & dataInfo,uint32_t length,const MessageInfo & info)188 std::pair<Status, int32_t> SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId,
189 const DataInfo &dataInfo, uint32_t length, const MessageInfo &info)
190 {
191 std::shared_ptr<SoftBusClient> conn = GetConnect(pipeInfo, deviceId, dataInfo.extraInfo);
192 if (conn == nullptr) {
193 return std::make_pair(Status::ERROR, 0);
194 }
195 auto status = conn->CheckStatus();
196 if (status == Status::RATE_LIMIT) {
197 return std::make_pair(Status::RATE_LIMIT, 0);
198 }
199 if (status != Status::SUCCESS) {
200 return OpenConnect(conn, deviceId);
201 }
202 status = conn->SendData(dataInfo);
203 if ((status != Status::NETWORK_ERROR) && (status != Status::RATE_LIMIT)) {
204 GetExpireTime(conn);
205 }
206 auto errCode = conn->GetSoftBusError();
207 return std::make_pair(status, errCode);
208 }
209
ConfigSessionAccessInfo(const ExtraDataInfo & extraInfo,SessionAccessInfo & sessionAccessInfo)210 bool SoftBusAdapter::ConfigSessionAccessInfo(const ExtraDataInfo &extraInfo, SessionAccessInfo &sessionAccessInfo)
211 {
212 if (extraInfo.userId.empty() || (extraInfo.bundleName.empty() && extraInfo.appId.empty()) ||
213 extraInfo.storeId.empty()) {
214 ZLOGE("extraInfo is empty, userId:%{public}s, bundleName:%{public}s, appId:%{public}s, storeId:%{public}s",
215 extraInfo.userId.c_str(), extraInfo.bundleName.c_str(), extraInfo.appId.c_str(),
216 Anonymous::Change(extraInfo.storeId).c_str());
217 return false;
218 }
219 AppIDMetaData appIdMeta;
220 if (extraInfo.bundleName.empty() && !MetaDataManager::GetInstance().LoadMeta(extraInfo.appId, appIdMeta, true)) {
221 ZLOGE("load appIdMeta fail, appId:%{public}s", extraInfo.appId.c_str());
222 return false;
223 }
224 StoreMetaData metaData;
225 metaData.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid;
226 metaData.user = extraInfo.userId == DEFAULT_USER ? SYSTEM_USER : extraInfo.userId;
227 metaData.bundleName = extraInfo.bundleName.empty() ? appIdMeta.bundleName : extraInfo.bundleName;
228 metaData.storeId = extraInfo.storeId;
229 if ((extraInfo.tokenId == 0) && !MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyWithoutPath(), metaData)) {
230 ZLOGE("get meta data fail, metaKey:%{public}s", Anonymous::Change(metaData.GetKeyWithoutPath()).c_str());
231 return false;
232 }
233 sessionAccessInfo.bundleName = metaData.bundleName;
234 sessionAccessInfo.storeId = metaData.storeId;
235 sessionAccessInfo.tokenId = (extraInfo.tokenId != 0) ? extraInfo.tokenId : metaData.tokenId;
236 int foregroundUserId = 0;
237 auto ret = AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId);
238 if (!ret) {
239 return false;
240 }
241 sessionAccessInfo.userId = foregroundUserId;
242 auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId();
243 if (accountId.empty()) {
244 return false;
245 }
246 sessionAccessInfo.accountId = accountId;
247 return true;
248 }
249
GetConnect(const PipeInfo & pipeInfo,const DeviceId & deviceId,const ExtraDataInfo & extraInfo)250 std::shared_ptr<SoftBusClient> SoftBusAdapter::GetConnect(const PipeInfo &pipeInfo, const DeviceId &deviceId,
251 const ExtraDataInfo &extraInfo)
252 {
253 std::string networkId = DeviceManagerAdapter::GetInstance().ToNetworkID(deviceId.deviceId);
254 if (networkId.empty()) {
255 ZLOGE("networkId is empty, deviceId:%{public}s", Anonymous::Change(deviceId.deviceId).c_str());
256 return nullptr;
257 }
258 std::shared_ptr<SoftBusClient> conn;
259 auto isOHType = DeviceManagerAdapter::GetInstance().IsOHOSType(deviceId.deviceId);
260 SessionAccessInfo sessionAccessInfo = { .isOHType = isOHType };
261 if (isOHType && !ConfigSessionAccessInfo(extraInfo, sessionAccessInfo)) {
262 ZLOGE("peer device is not oh device or config accessInfo fail, deviceId:%{public}s",
263 Anonymous::Change(deviceId.deviceId).c_str());
264 return nullptr;
265 }
266 uint32_t qosType = isOHType ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR;
267 connects_.Compute(deviceId.deviceId,
268 [&pipeInfo, &deviceId, &sessionAccessInfo, &conn, qosType, &networkId](const auto &key,
269 std::vector<std::shared_ptr<SoftBusClient>> &connects) -> bool {
270 for (auto &connect : connects) {
271 if (connect == nullptr) {
272 continue;
273 }
274 if (connect->GetQoSType() == qosType) {
275 conn = connect;
276 return true;
277 }
278 }
279 auto connect = std::make_shared<SoftBusClient>(pipeInfo, deviceId, networkId, qosType, sessionAccessInfo);
280 connects.emplace_back(connect);
281 conn = connect;
282 return true;
283 });
284 return conn;
285 }
286
OpenConnect(const std::shared_ptr<SoftBusClient> & conn,const DeviceId & deviceId)287 std::pair<Status, int32_t> SoftBusAdapter::OpenConnect(const std::shared_ptr<SoftBusClient> &conn,
288 const DeviceId &deviceId)
289 {
290 auto networkId = DeviceManagerAdapter::GetInstance().ToNetworkID(deviceId.deviceId);
291 if (conn != nullptr) {
292 auto oldNetworkId = conn->GetNetworkId();
293 if (networkId != oldNetworkId) {
294 ZLOGI("peer networkId changed, %{public}s->%{public}s", Anonymous::Change(oldNetworkId).c_str(),
295 Anonymous::Change(networkId).c_str());
296 conn->UpdateNetworkId(networkId);
297 }
298 }
299 auto applyTask = [deviceId](int32_t errcode) {
300 CommunicatorContext::GetInstance().NotifySessionReady(deviceId.deviceId, errcode);
301 };
302 auto connectTask = [this, connect = std::weak_ptr<SoftBusClient>(conn)]() {
303 auto conn = connect.lock();
304 if (conn != nullptr) {
305 conn->OpenConnect(&clientListener_);
306 }
307 };
308 ConnectManager::GetInstance()->ApplyConnect(networkId, applyTask, connectTask);
309 return std::make_pair(Status::RATE_LIMIT, 0);
310 }
311
StartCloseSessionTask(const std::string & deviceId)312 void SoftBusAdapter::StartCloseSessionTask(const std::string &deviceId)
313 {
314 std::shared_ptr<SoftBusClient> conn;
315 bool isOHOSType = DeviceManagerAdapter::GetInstance().IsOHOSType(deviceId);
316 uint32_t qosType = isOHOSType ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR;
317 auto connects = connects_.Find(deviceId);
318 if (!connects.first) {
319 return;
320 }
321 for (auto &connect : connects.second) {
322 if (connect->GetQoSType() == qosType) {
323 conn = connect;
324 break;
325 }
326 }
327 if (conn == nullptr) {
328 return;
329 }
330 Time now = std::chrono::steady_clock::now();
331 auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now;
332 lock_guard<decltype(taskMutex_)> lock(taskMutex_);
333 if (taskId_ == ExecutorPool::INVALID_TASK_ID) {
334 ZLOGI("Start close session, deviceId:%{public}s", Anonymous::Change(deviceId).c_str());
335 taskId_ = CommunicatorContext::GetInstance().GetThreadPool()->Schedule(expireTime - now, GetCloseSessionTask());
336 next_ = expireTime;
337 }
338 }
339
GetCloseSessionTask()340 SoftBusAdapter::Task SoftBusAdapter::GetCloseSessionTask()
341 {
342 return [this]() mutable {
343 Time now = std::chrono::steady_clock::now();
344 std::vector<std::shared_ptr<SoftBusClient>> connToClose;
345 connects_.ForEach([&now, &connToClose](const auto &key, auto &connects) -> bool {
346 std::vector<std::shared_ptr<SoftBusClient>> holdConnects;
347 for (auto conn : connects) {
348 if (conn == nullptr) {
349 continue;
350 }
351 auto expireTime = conn->GetExpireTime();
352 if (expireTime <= now) {
353 ZLOGI("[timeout] close session socket:%{public}d", conn->GetSocket());
354 connToClose.emplace_back(conn);
355 } else {
356 holdConnects.emplace_back(conn);
357 }
358 }
359 connects = std::move(holdConnects);
360 return false;
361 });
362 connects_.EraseIf([](const auto &key, const auto &conn) -> bool {
363 if (conn.empty()) {
364 ConnectManager::GetInstance()->OnSessionClose(DeviceManagerAdapter::GetInstance().ToNetworkID(key));
365 }
366 return conn.empty();
367 });
368 Time next = INVALID_NEXT;
369 lock_guard<decltype(taskMutex_)> lg(taskMutex_);
370 connects_.ForEach([&next](const auto &key, auto &connects) -> bool {
371 for (auto conn : connects) {
372 if (conn == nullptr) {
373 continue;
374 }
375 auto expireTime = conn->GetExpireTime();
376 if (expireTime < next) {
377 next = expireTime;
378 }
379 }
380 return false;
381 });
382 if (next == INVALID_NEXT) {
383 taskId_ = ExecutorPool::INVALID_TASK_ID;
384 return;
385 }
386 taskId_ = CommunicatorContext::GetInstance().GetThreadPool()->Schedule(
387 next > now ? next - now : ExecutorPool::INVALID_DELAY, GetCloseSessionTask());
388 next_ = next;
389 };
390 }
391
GetMtuSize(const DeviceId & deviceId)392 uint32_t SoftBusAdapter::GetMtuSize(const DeviceId &deviceId)
393 {
394 uint32_t mtuSize = DEFAULT_MTU_SIZE;
395 connects_.ComputeIfPresent(deviceId.deviceId, [&mtuSize](auto, auto &connects) {
396 uint32_t mtu = 0;
397 for (auto conn : connects) {
398 if (conn == nullptr) {
399 continue;
400 }
401 if (mtu < conn->GetMtuBuffer()) {
402 mtu = conn->GetMtuBuffer();
403 }
404 }
405 if (mtu != 0) {
406 mtuSize = mtu;
407 }
408 return true;
409 });
410 return mtuSize;
411 }
412
GetTimeout(const DeviceId & deviceId)413 uint32_t SoftBusAdapter::GetTimeout(const DeviceId &deviceId)
414 {
415 return DEFAULT_TIMEOUT;
416 }
417
DelConnect(int32_t socket,bool isForce)418 std::string SoftBusAdapter::DelConnect(int32_t socket, bool isForce)
419 {
420 std::string name;
421 std::set<std::string> closedConnect;
422 connects_.EraseIf([socket, isForce, &name, &closedConnect](const auto &deviceId, auto &connects) -> bool {
423 if (!isForce && DeviceManagerAdapter::GetInstance().IsOHOSType(deviceId)) {
424 return false;
425 }
426 std::string networkId;
427 for (auto iter = connects.begin(); iter != connects.end();) {
428 if (*iter != nullptr && **iter == socket) {
429 name += deviceId;
430 name += " ";
431 networkId = (*iter)->GetNetworkId();
432 iter = connects.erase(iter);
433 } else {
434 iter++;
435 }
436 }
437 if (connects.empty() && !networkId.empty()) {
438 closedConnect.insert(std::move(networkId));
439 return true;
440 }
441 return false;
442 });
443 for (const auto &networkId : closedConnect) {
444 ConnectManager::GetInstance()->OnSessionClose(networkId);
445 }
446 return name;
447 }
448
OnClientShutdown(int32_t socket,bool isForce)449 std::string SoftBusAdapter::OnClientShutdown(int32_t socket, bool isForce)
450 {
451 return DelConnect(socket, isForce);
452 }
453
IsSameStartedOnPeer(const struct PipeInfo & pipeInfo,const struct DeviceId & peer)454 bool SoftBusAdapter::IsSameStartedOnPeer(const struct PipeInfo &pipeInfo,
455 __attribute__((unused)) const struct DeviceId &peer)
456 {
457 ZLOGI("pipeInfo:%{public}s deviceId:%{public}s", pipeInfo.pipeId.c_str(),
458 Anonymous::Change(peer.deviceId).c_str());
459 return true;
460 }
461
SetMessageTransFlag(const PipeInfo & pipeInfo,bool flag)462 void SoftBusAdapter::SetMessageTransFlag(const PipeInfo &pipeInfo, bool flag)
463 {
464 ZLOGI("pipeInfo:%{public}s, flag:%{public}d", pipeInfo.pipeId.c_str(), flag);
465 flag_ = flag;
466 }
467
CreateSessionServerAdapter(const std::string & sessionName)468 int SoftBusAdapter::CreateSessionServerAdapter(const std::string &sessionName)
469 {
470 ZLOGD("begin");
471 SocketInfo socketInfo;
472 std::string sessionServerName = sessionName;
473 socketInfo.name = const_cast<char *>(sessionServerName.c_str());
474 std::string pkgName = "ohos.distributeddata";
475 socketInfo.pkgName = pkgName.data();
476 socket_ = Socket(socketInfo);
477 return Listen(socket_, Qos, QOS_COUNT, &serverListener_);
478 }
479
RemoveSessionServerAdapter(const std::string & sessionName) const480 int SoftBusAdapter::RemoveSessionServerAdapter(const std::string &sessionName) const
481 {
482 ZLOGD("begin");
483 Shutdown(socket_);
484 return 0;
485 }
486
NotifyDataListeners(const uint8_t * data,int size,const std::string & deviceId,const PipeInfo & pipeInfo)487 void SoftBusAdapter::NotifyDataListeners(const uint8_t *data, int size, const std::string &deviceId,
488 const PipeInfo &pipeInfo)
489 {
490 ZLOGD("begin");
491 auto ret = dataChangeListeners_.ComputeIfPresent(pipeInfo.pipeId,
492 [&data, &size, &deviceId, &pipeInfo](const auto &key, const AppDataChangeListener *&value) {
493 ZLOGD("ready to notify, pipeName:%{public}s, deviceId:%{public}s.", pipeInfo.pipeId.c_str(),
494 Anonymous::Change(deviceId).c_str());
495 DeviceInfo deviceInfo = DeviceManagerAdapter::GetInstance().GetDeviceInfo(deviceId);
496 value->OnMessage(deviceInfo, data, size, pipeInfo);
497 return true;
498 });
499 if (!ret) {
500 ZLOGW("no listener %{public}s.", pipeInfo.pipeId.c_str());
501 }
502 }
503
Broadcast(const PipeInfo & pipeInfo,const LevelInfo & levelInfo)504 Status SoftBusAdapter::Broadcast(const PipeInfo &pipeInfo, const LevelInfo &levelInfo)
505 {
506 DataLevel level = {
507 .dynamicLevel = levelInfo.dynamic,
508 .staticLevel = levelInfo.statics,
509 .switchLevel = levelInfo.switches,
510 .switchLength = levelInfo.switchesLen,
511 };
512 auto status = SetDataLevel(&level);
513 if (status == SOFTBUS_FUNC_NOT_SUPPORT) {
514 return Status::NOT_SUPPORT_BROADCAST;
515 }
516 return status != SOFTBUS_OK ? Status::ERROR : Status::SUCCESS;
517 }
518
OnBroadcast(const DeviceId & device,const LevelInfo & levelInfo)519 void SoftBusAdapter::OnBroadcast(const DeviceId &device, const LevelInfo &levelInfo)
520 {
521 ZLOGI("device:%{public}s", Anonymous::Change(device.deviceId).c_str());
522 if (!onBroadcast_) {
523 ZLOGW("no listener device:%{public}s", Anonymous::Change(device.deviceId).c_str());
524 return;
525 }
526 onBroadcast_(device.deviceId, levelInfo);
527 }
528
ListenBroadcastMsg(const PipeInfo & pipeInfo,std::function<void (const std::string &,const LevelInfo &)> listener)529 int32_t SoftBusAdapter::ListenBroadcastMsg(const PipeInfo &pipeInfo,
530 std::function<void(const std::string &, const LevelInfo &)> listener)
531 {
532 if (onBroadcast_) {
533 return SOFTBUS_ALREADY_EXISTED;
534 }
535 onBroadcast_ = std::move(listener);
536 return RegDataLevelChangeCb(pipeInfo.pipeId.c_str(), &g_callback);
537 }
538
SetDataHandler(SoftBusAdapter * handler)539 void AppDataListenerWrap::SetDataHandler(SoftBusAdapter *handler)
540 {
541 ZLOGI("begin");
542 softBusAdapter_ = handler;
543 }
544
OnClientShutdown(int32_t socket,ShutdownReason reason)545 void AppDataListenerWrap::OnClientShutdown(int32_t socket, ShutdownReason reason)
546 {
547 // when the local close the session, this callback function will not be triggered;
548 // when the current function is called, soft bus has released the session resource, only connId is valid;
549 std::string name = softBusAdapter_->OnClientShutdown(socket);
550 ZLOGI("[shutdown] socket:%{public}d, name:%{public}s", socket, Anonymous::Change(name).c_str());
551 }
552
OnClientBytesReceived(int32_t socket,const void * data,uint32_t dataLen)553 void AppDataListenerWrap::OnClientBytesReceived(int32_t socket, const void *data, uint32_t dataLen) {}
554
OnClientSocketChanged(int32_t socket,QoSEvent eventId,const QosTV * qos,uint32_t qosCount)555 void AppDataListenerWrap::OnClientSocketChanged(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount)
556 {
557 if (eventId == QoSEvent::QOS_SATISFIED && qos != nullptr && qos[0].qos == QOS_TYPE_MIN_BW && qosCount == 1) {
558 auto name = softBusAdapter_->OnClientShutdown(socket, false);
559 ZLOGI("[SocketChanged] socket:%{public}d, name:%{public}s", socket, Anonymous::Change(name).c_str());
560 }
561 }
562
OnServerBind(int32_t socket,PeerSocketInfo info)563 void AppDataListenerWrap::OnServerBind(int32_t socket, PeerSocketInfo info)
564 {
565 softBusAdapter_->OnBind(socket, info);
566 std::string peerDevUuid = DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(std::string(info.networkId));
567
568 ZLOGI("[OnServerBind] socket:%{public}d, peer name:%{public}s, peer devId:%{public}s", socket, info.name,
569 Anonymous::Change(peerDevUuid).c_str());
570 }
571
OnServerShutdown(int32_t socket,ShutdownReason reason)572 void AppDataListenerWrap::OnServerShutdown(int32_t socket, ShutdownReason reason)
573 {
574 softBusAdapter_->OnServerShutdown(socket);
575 ZLOGI("Shut down reason:%{public}d socket id:%{public}d", reason, socket);
576 }
577
OnServerBytesReceived(int32_t socket,const void * data,uint32_t dataLen)578 void AppDataListenerWrap::OnServerBytesReceived(int32_t socket, const void *data, uint32_t dataLen)
579 {
580 SoftBusAdapter::ServerSocketInfo info;
581 if (!softBusAdapter_->GetPeerSocketInfo(socket, info)) {
582 ZLOGE("Get peer socket info failed, socket id %{public}d", socket);
583 return;
584 };
585 std::string peerDevUuid = DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(std::string(info.networkId));
586 ZLOGD("[OnBytesReceived] socket:%{public}d, peer name:%{public}s, peer devId:%{public}s, data len:%{public}u",
587 socket, info.name.c_str(), Anonymous::Change(peerDevUuid).c_str(), dataLen);
588
589 std::string pipeId = GetPipeId(info.name);
590 if (pipeId.empty()) {
591 ZLOGE("pipId is invalid");
592 return;
593 }
594
595 NotifyDataListeners(reinterpret_cast<const uint8_t *>(data), dataLen, peerDevUuid, { pipeId, "" });
596 }
597
LoadMetaData(const std::string & bundleName,const std::string & storeId,int32_t userId)598 std::pair<bool, StoreMetaData> AppDataListenerWrap::LoadMetaData(const std::string &bundleName,
599 const std::string &storeId, int32_t userId)
600 {
601 StoreMetaData metaData;
602 metaData.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid;
603 metaData.bundleName = bundleName;
604 metaData.storeId = storeId;
605 metaData.user = std::to_string(userId);
606 auto ret = MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyWithoutPath(), metaData);
607 if (!ret) {
608 metaData.user = SYSTEM_USER;
609 ret = MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyWithoutPath(), metaData);
610 }
611 return { ret, metaData };
612 }
613
OnServerAccessCheck(int32_t socket,PeerSocketInfo info,SocketAccessInfo * peerInfo,SocketAccessInfo * localInfo)614 bool AppDataListenerWrap::OnServerAccessCheck(int32_t socket, PeerSocketInfo info, SocketAccessInfo *peerInfo,
615 SocketAccessInfo *localInfo)
616 {
617 ZLOGI("receive bind request, socket:%{public}d", socket);
618 if (peerInfo == nullptr || localInfo == nullptr) {
619 ZLOGE("peerInfo or localInfo is nullptr, peerInfo:%{public}d, localInfo:%{public}d", peerInfo == nullptr,
620 localInfo == nullptr);
621 return false;
622 }
623 SoftBusClient::AccessExtraInfo peerExtraInfo;
624 if (!DistributedData::Serializable::Unmarshall(peerInfo->extraAccessInfo, peerExtraInfo)) {
625 ZLOGE("Unmarshall failed, peer extraAccessInfo:%{public}s", peerInfo->extraAccessInfo);
626 return false;
627 }
628 int foregroundUserId = 0;
629 if (!AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId)) {
630 return false;
631 }
632 localInfo->userId = foregroundUserId;
633 auto resultPair = LoadMetaData(peerExtraInfo.bundleName, peerExtraInfo.storeId, foregroundUserId);
634 if (!resultPair.first) {
635 ZLOGE("local device has no store, bundleName:%{public}s", peerExtraInfo.bundleName.c_str());
636 return false;
637 }
638 localInfo->localTokenId = resultPair.second.tokenId;
639 auto type = AccessTokenKit::GetTokenTypeFlag(resultPair.second.tokenId);
640 if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
641 ZLOGW("this is system service sync, bundleName:%{public}s", peerExtraInfo.bundleName.c_str());
642 return true;
643 }
644 AclParams aclParams;
645 aclParams.accCaller.bundleName = peerExtraInfo.bundleName;
646 aclParams.accCaller.accountId = AccountDelegate::GetInstance()->GetCurrentAccountId();
647 aclParams.accCaller.userId = foregroundUserId;
648 aclParams.accCaller.networkId = DeviceManagerAdapter::GetInstance().GetLocalDevice().networkId;
649 aclParams.accCallee.accountId = peerExtraInfo.accountId;
650 aclParams.accCallee.userId = peerInfo->userId;
651 aclParams.accCallee.networkId = std::string(info.networkId);
652 bool accessFlag = false;
653 if (resultPair.second.authType == AuthType::IDENTICAL_ACCOUNT) {
654 accessFlag = DeviceManagerAdapter::GetInstance().IsSameAccount(aclParams.accCaller, aclParams.accCallee);
655 } else {
656 accessFlag = DeviceManagerAdapter::GetInstance().CheckAccessControl(aclParams.accCaller, aclParams.accCallee);
657 }
658 return accessFlag;
659 }
660
GetPipeId(const std::string & name)661 std::string AppDataListenerWrap::GetPipeId(const std::string &name)
662 {
663 auto pos = name.find('_');
664 if (pos != std::string::npos) {
665 return name.substr(0, pos);
666 }
667 return name;
668 }
669
NotifyDataListeners(const uint8_t * data,const int size,const std::string & deviceId,const PipeInfo & pipeInfo)670 void AppDataListenerWrap::NotifyDataListeners(const uint8_t *data, const int size, const std::string &deviceId,
671 const PipeInfo &pipeInfo)
672 {
673 softBusAdapter_->NotifyDataListeners(data, size, deviceId, pipeInfo);
674 }
675
GetPeerSocketInfo(int32_t socket,ServerSocketInfo & info)676 bool SoftBusAdapter::GetPeerSocketInfo(int32_t socket, ServerSocketInfo &info)
677 {
678 auto it = peerSocketInfos_.Find(socket);
679 if (it.first) {
680 info = it.second;
681 return true;
682 }
683 return false;
684 }
685
OnBind(int32_t socket,PeerSocketInfo info)686 void SoftBusAdapter::OnBind(int32_t socket, PeerSocketInfo info)
687 {
688 ServerSocketInfo socketInfo;
689 socketInfo.name = std::string(info.name);
690 socketInfo.networkId = std::string(info.networkId);
691 socketInfo.pkgName = std::string(info.pkgName);
692 peerSocketInfos_.Insert(socket, socketInfo);
693 }
694
OnServerShutdown(int32_t socket)695 void SoftBusAdapter::OnServerShutdown(int32_t socket)
696 {
697 peerSocketInfos_.Erase(socket);
698 }
699
CloseSession(const std::string & networkId)700 bool SoftBusAdapter::CloseSession(const std::string &networkId)
701 {
702 auto uuid = DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(networkId);
703 auto ret = connects_.Erase(uuid);
704 if (ret != 0) {
705 ConnectManager::GetInstance()->OnSessionClose(networkId);
706 }
707 return ret != 0;
708 }
709
ReuseConnect(const PipeInfo & pipeInfo,const DeviceId & deviceId,const ExtraDataInfo & extraInfo)710 Status SoftBusAdapter::ReuseConnect(const PipeInfo &pipeInfo, const DeviceId &deviceId, const ExtraDataInfo &extraInfo)
711 {
712 bool isOHOSType = DeviceManagerAdapter::GetInstance().IsOHOSType(deviceId.deviceId);
713 if (!isOHOSType) {
714 return Status::NOT_SUPPORT;
715 }
716 std::shared_ptr<SoftBusClient> conn = GetConnect(pipeInfo, deviceId, extraInfo);
717 if (conn == nullptr) {
718 return Status::ERROR;
719 }
720 auto status = conn->ReuseConnect(&clientListener_);
721 if (status != Status::SUCCESS) {
722 return status;
723 }
724 uint32_t qosType = SoftBusClient::QOS_HML;
725 // Avoid being cleared by scheduled tasks
726 connects_.Compute(deviceId.deviceId, [&conn, qosType](const auto &key,
727 std::vector<std::shared_ptr<SoftBusClient>> &connects) -> bool {
728 for (auto &connect : connects) {
729 if (connect == nullptr) {
730 continue;
731 }
732 if (connect->GetQoSType() == qosType) {
733 return true;
734 }
735 }
736 connects.emplace_back(conn);
737 return true;
738 });
739 StartCloseSessionTask(deviceId.deviceId);
740 return Status::SUCCESS;
741 }
742 } // namespace AppDistributedKv
743 } // namespace OHOS