1 /*
2 * Copyright (c) 2024 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 #include "p2p_entity.h"
16
17 #include <algorithm>
18 #include <future>
19
20 #include "conn_log.h"
21 #include "softbus_error_code.h"
22
23 #include "data/interface_manager.h"
24 #include "data/link_manager.h"
25 #include "p2p_available_state.h"
26 #include "p2p_broadcast_receiver.h"
27 #include "utils/wifi_direct_anonymous.h"
28 #include "wifi_direct_scheduler_factory.h"
29
30 namespace OHOS::SoftBus {
31 using InterfaceType = InterfaceInfo::InterfaceType;
32
P2pStateChangeCallback(P2pState state)33 static void P2pStateChangeCallback(P2pState state)
34 {
35 CONN_LOGI(CONN_WIFI_DIRECT, "state=%{public}d", state);
36 BroadcastParam param {};
37 param.p2pState = state;
38 P2pBroadcast::GetInstance()->DispatchWorkHandler(BroadcastReceiverAction::WIFI_P2P_STATE_CHANGED_ACTION, param);
39 }
40
P2pConnectionChangeCallback(const WifiP2pLinkedInfo info)41 static void P2pConnectionChangeCallback(const WifiP2pLinkedInfo info)
42 {
43 CONN_LOGI(CONN_WIFI_DIRECT, "ConnectionState=%{public}d, isGroupOwner=%{public}d", info.connectState,
44 info.isP2pGroupOwner);
45 BroadcastParam param;
46 param.p2pLinkInfo = info;
47 param.groupInfo = std::make_shared<P2pAdapter::WifiDirectP2pGroupInfo>();
48 auto ret = P2pAdapter::GetGroupInfo(*(param.groupInfo));
49 if (ret != SOFTBUS_OK) {
50 CONN_LOGI(CONN_WIFI_DIRECT, "get group info failed, error=%{public}d", ret);
51 param.groupInfo = nullptr;
52 }
53 P2pBroadcast::GetInstance()->DispatchWorkHandler(
54 BroadcastReceiverAction::WIFI_P2P_CONNECTION_CHANGED_ACTION, param);
55 }
56
Listener(BroadcastReceiverAction action,const struct BroadcastParam & param)57 void P2pEntity::Listener(BroadcastReceiverAction action, const struct BroadcastParam ¶m)
58 {
59 if (action == BroadcastReceiverAction::WIFI_P2P_STATE_CHANGED_ACTION) {
60 CONN_LOGI(CONN_WIFI_DIRECT, "WIFI_P2P_STATE_CHANGED_ACTION");
61 P2pEntity::GetInstance().OnP2pStateChangeEvent(param.p2pState);
62 } else if (action == BroadcastReceiverAction::WIFI_P2P_CONNECTION_CHANGED_ACTION) {
63 CONN_LOGI(CONN_WIFI_DIRECT, "WIFI_P2P_CONNECTION_CHANGED_ACTION");
64 P2pEntity::GetInstance().OnP2pConnectionChangeEvent(param.p2pLinkInfo, param.groupInfo);
65 }
66 }
67
Init()68 void P2pEntity::Init()
69 {
70 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
71 BroadcastReceiverAction actions[2] = {
72 BroadcastReceiverAction::WIFI_P2P_STATE_CHANGED_ACTION,
73 BroadcastReceiverAction::WIFI_P2P_CONNECTION_CHANGED_ACTION,
74 };
75 P2pBroadcast::GetInstance()->RegisterBroadcastListener(
76 actions, ARRAY_SIZE(actions), "P2pEntity", ListenerPriority::LISTENER_PRIORITY_HIGH, P2pEntity::Listener);
77 RegisterP2pStateChangedCallback(P2pStateChangeCallback);
78 RegisterP2pConnectionChangedCallback(P2pConnectionChangeCallback);
79
80 /* The P2P may report the event through callback early, and softbus register the callback later.
81 * Therefore, after theregistration is successful, check wethere the P2P is enable. */
82 InterfaceManager::GetInstance().InitInterface(InterfaceInfo::InterfaceType::P2P);
83 }
84
P2pEntity()85 P2pEntity::P2pEntity() : timer_("P2pEntity")
86 {
87 state_ = P2pAvailableState::Instance();
88 }
89
DisconnectLink(const std::string & remoteMac)90 void P2pEntity::DisconnectLink(const std::string &remoteMac)
91 {
92 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
93 P2pAdapter::WifiDirectP2pGroupInfo groupInfo {};
94 auto ret = P2pAdapter::GetGroupInfo(groupInfo);
95 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_WIFI_DIRECT, "get group info failed");
96 bool isNeedRemove = true;
97 if (groupInfo.isGroupOwner) {
98 if (groupInfo.clientDevices.size() > 1) {
99 isNeedRemove = false;
100 }
101 if ((groupInfo.clientDevices.size() == 1 && remoteMac == groupInfo.clientDevices[0].address) ||
102 groupInfo.clientDevices.size() == 0) {
103 isNeedRemove = true;
104 }
105 }
106 if (isNeedRemove) {
107 P2pAdapter::DestroyGroupParam params;
108 params.interface = IF_NAME_P2P0;
109 DestroyGroup(params);
110 }
111 }
112
DestroyGroupIfNeeded()113 void P2pEntity::DestroyGroupIfNeeded() { };
114
CreateGroup(const P2pCreateGroupParam & param)115 P2pOperationResult P2pEntity::CreateGroup(const P2pCreateGroupParam ¶m)
116 {
117 std::shared_ptr<P2pOperationWrapper<P2pCreateGroupParam>> operation;
118 P2pOperationResult result;
119 {
120 std::lock_guard lock(operationLock_);
121 operation = std::make_shared<P2pOperationWrapper<P2pCreateGroupParam>>(param, P2pOperationType::CREATE_GROUP);
122 int ret = state_->CreateGroup(operation);
123 if (ret != SOFTBUS_OK) {
124 result.errorCode_ = ret;
125 return result;
126 }
127 }
128
129 CONN_LOGI(CONN_WIFI_DIRECT, "wait to be done");
130 return operation->promise_.get_future().get();
131 }
132
Connect(const P2pConnectParam & param)133 P2pOperationResult P2pEntity::Connect(const P2pConnectParam ¶m)
134 {
135 std::shared_ptr<P2pOperationWrapper<P2pConnectParam>> operation;
136 P2pOperationResult result;
137 {
138 std::lock_guard lock(operationLock_);
139 operation = std::make_shared<P2pOperationWrapper<P2pConnectParam>>(param, P2pOperationType::CONNECT);
140 int ret = state_->Connect(operation);
141 result.errorCode_ = ret;
142 if (ret != SOFTBUS_OK) {
143 return result;
144 }
145 }
146
147 CONN_LOGI(CONN_WIFI_DIRECT, "wait to be done");
148 return operation->promise_.get_future().get();
149 }
150
ReuseLink()151 int32_t P2pEntity::ReuseLink()
152 {
153 int32_t ret = P2pAdapter::P2pShareLinkReuse();
154 if (ret != SOFTBUS_OK) {
155 return ret;
156 }
157 return ret;
158 }
159
SendClientJoinEvent(const std::string & remoteMac,int32_t result)160 static void SendClientJoinEvent(const std::string &remoteMac, int32_t result)
161 {
162 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
163 std::string remoteDeviceId;
164 auto success = LinkManager::GetInstance().ProcessIfPresent(remoteMac, [&remoteDeviceId](InnerLink &link) {
165 remoteDeviceId = link.GetRemoteDeviceId();
166 });
167 CONN_CHECK_AND_RETURN_LOGW(
168 success, CONN_WIFI_DIRECT, "link not found, remote mac=%{public}s", WifiDirectAnonymizeMac(remoteMac).c_str());
169
170 ClientJoinEvent event { result, remoteDeviceId, remoteMac };
171 WifiDirectSchedulerFactory::GetInstance().GetScheduler().ProcessEvent(remoteDeviceId, event);
172 }
173
NotifyNewClientJoining(const std::string & remoteMac)174 void P2pEntity::NotifyNewClientJoining(const std::string &remoteMac)
175 {
176 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
177 CONN_CHECK_AND_RETURN_LOGW(!remoteMac.empty(), CONN_WIFI_DIRECT, "remote mac is empty, skip");
178 std::lock_guard lock(joiningClientsLock_);
179 if (joiningClients_.empty()) {
180 timer_.Setup();
181 }
182
183 auto timerId = timer_.Register(
184 [this, remoteMac]() {
185 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
186 std::lock_guard lock(joiningClientsLock_);
187 SendClientJoinEvent(remoteMac, SOFTBUS_CONN_PV1_CONNECT_GROUP_TIMEOUT);
188 joiningClients_.erase(remoteMac);
189 if (joiningClients_.empty()) {
190 timer_.Shutdown(false);
191 }
192 },
193 TIMEOUT_WAIT_CLIENT_JOIN_MS, true);
194 joiningClients_[remoteMac] = timerId;
195 CONN_LOGI(CONN_WIFI_DIRECT, "remoteMac=%{public}s, joining client count=%{public}zu",
196 WifiDirectAnonymizeMac(remoteMac).c_str(), joiningClients_.size());
197 }
198
CancelNewClientJoining(const std::string & remoteMac)199 void P2pEntity::CancelNewClientJoining(const std::string &remoteMac)
200 {
201 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
202 CONN_CHECK_AND_RETURN_LOGW(!remoteMac.empty(), CONN_WIFI_DIRECT, "remote mac is empty, skip");
203 std::lock_guard lock(joiningClientsLock_);
204 auto it = joiningClients_.find(remoteMac);
205 if (it == joiningClients_.end()) {
206 CONN_LOGI(CONN_WIFI_DIRECT, "remoteMac=%{public}s not exist, joining client count=%{public}zu",
207 WifiDirectAnonymizeMac(remoteMac).c_str(), joiningClients_.size());
208 return;
209 }
210 timer_.Unregister(it->second);
211 joiningClients_.erase(it);
212 if (joiningClients_.empty()) {
213 timer_.Shutdown(false);
214 }
215 CONN_LOGI(CONN_WIFI_DIRECT, "remoteMac=%{public}s, joining client count=%{public}zu",
216 WifiDirectAnonymizeMac(remoteMac).c_str(), joiningClients_.size());
217 }
218
RemoveNewClientJoining(const std::string & remoteMac)219 void P2pEntity::RemoveNewClientJoining(const std::string &remoteMac)
220 {
221 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
222 CONN_CHECK_AND_RETURN_LOGW(!remoteMac.empty(), CONN_WIFI_DIRECT, "remote mac is empty, skip");
223 std::lock_guard lock(joiningClientsLock_);
224 auto it = joiningClients_.find(remoteMac);
225 if (it == joiningClients_.end()) {
226 CONN_LOGI(CONN_WIFI_DIRECT, "remoteMac=%{public}s not exist, joining client count=%{public}zu",
227 WifiDirectAnonymizeMac(remoteMac).c_str(), joiningClients_.size());
228 return;
229 }
230 timer_.Unregister(it->second);
231 SendClientJoinEvent(remoteMac, SOFTBUS_OK);
232 joiningClients_.erase(it);
233 if (joiningClients_.empty()) {
234 timer_.Shutdown(false);
235 }
236 }
237
ClearJoiningClient()238 void P2pEntity::ClearJoiningClient()
239 {
240 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
241 std::lock_guard lock(joiningClientsLock_);
242 if (joiningClients_.empty()) {
243 return;
244 }
245 for (const auto &kv : joiningClients_) {
246 timer_.Unregister(kv.second);
247 SendClientJoinEvent(kv.first, SOFTBUS_CONN_P2P_CLEAR_JOIN_CLIENTS_FAILED);
248 }
249 joiningClients_.clear();
250 timer_.Shutdown(false);
251 }
252
GetJoiningClientCount()253 size_t P2pEntity::GetJoiningClientCount()
254 {
255 std::lock_guard lock(joiningClientsLock_);
256 return joiningClients_.size();
257 }
258
Disconnect(const P2pDestroyGroupParam & param)259 P2pOperationResult P2pEntity::Disconnect(const P2pDestroyGroupParam ¶m)
260 {
261 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
262 std::shared_ptr<P2pOperationWrapper<P2pDestroyGroupParam>> operation = nullptr;
263 P2pOperationResult result;
264 int reuseCount = 0;
265 {
266 std::lock_guard lock(operationLock_);
267 auto ret =
268 InterfaceManager::GetInstance().ReadInterface(InterfaceType::P2P, [&reuseCount](const InterfaceInfo &info) {
269 reuseCount = info.GetReuseCount();
270 return SOFTBUS_OK;
271 });
272 if (ret != SOFTBUS_OK) {
273 CONN_LOGI(CONN_WIFI_DIRECT, "get reuse cnt from interface info failed, error=%{public}d", ret);
274 result.errorCode_ = ret;
275 return result;
276 }
277
278 if (reuseCount > 1) {
279 CONN_LOGI(CONN_WIFI_DIRECT, "shareLinkRemoveGroupSync");
280 result.errorCode_ = P2pAdapter::P2pShareLinkRemoveGroup(param);
281 return result;
282 }
283
284 operation = std::make_shared<P2pOperationWrapper<P2pDestroyGroupParam>>(param, P2pOperationType::DESTROY_GROUP);
285 ret = state_->RemoveLink(operation);
286 result.errorCode_ = ret;
287 if (ret != SOFTBUS_OK) {
288 return result;
289 }
290 }
291 return operation->promise_.get_future().get();
292 }
293
DestroyGroup(const P2pDestroyGroupParam & param)294 P2pOperationResult P2pEntity::DestroyGroup(const P2pDestroyGroupParam ¶m)
295 {
296 std::shared_ptr<P2pOperationWrapper<P2pDestroyGroupParam>> operation;
297 P2pOperationResult result;
298 {
299 std::lock_guard lock(operationLock_);
300 operation = std::make_shared<P2pOperationWrapper<P2pDestroyGroupParam>>(param, P2pOperationType::DESTROY_GROUP);
301 int ret = state_->DestroyGroup(operation);
302 result.errorCode_ = ret;
303 if (ret != SOFTBUS_OK) {
304 return result;
305 }
306 }
307
308 CONN_LOGI(CONN_WIFI_DIRECT, "wait to be done");
309 return operation->promise_.get_future().get();
310 }
311
ChangeState(P2pEntityState * state,const std::shared_ptr<P2pOperation> & operation)312 void P2pEntity::ChangeState(P2pEntityState *state, const std::shared_ptr<P2pOperation> &operation)
313 {
314 std::lock_guard lock(operationLock_);
315 state_->Exit();
316 CONN_LOGI(CONN_WIFI_DIRECT, "%{public}s ==> %{public}s", state_->GetName().c_str(), state->GetName().c_str());
317 state_ = state;
318 state_->Enter(operation);
319 }
320
PushOperation(const std::shared_ptr<P2pOperation> & operation)321 void P2pEntity::PushOperation(const std::shared_ptr<P2pOperation> &operation)
322 {
323 std::lock_guard lock(pendingOperationLock_);
324 pendingOperations_.push(operation);
325 }
326
ExecuteNextOperation()327 void P2pEntity::ExecuteNextOperation()
328 {
329 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
330 std::shared_ptr<P2pOperation> operation;
331 {
332 std::lock_guard lock(pendingOperationLock_);
333 if (pendingOperations_.empty()) {
334 return;
335 }
336 operation = pendingOperations_.front();
337 pendingOperations_.pop();
338 }
339
340 int ret = SOFTBUS_OK;
341 P2pOperationResult result {};
342 switch (operation->type_) {
343 case P2pOperationType::CREATE_GROUP:
344 ret = state_->CreateGroup(std::dynamic_pointer_cast<P2pOperationWrapper<P2pCreateGroupParam>>(operation));
345 break;
346 case P2pOperationType::CONNECT:
347 ret = state_->Connect(std::dynamic_pointer_cast<P2pOperationWrapper<P2pConnectParam>>(operation));
348 break;
349 case P2pOperationType::DESTROY_GROUP:
350 ret = state_->DestroyGroup(std::dynamic_pointer_cast<P2pOperationWrapper<P2pDestroyGroupParam>>(operation));
351 break;
352 default:
353 CONN_LOGE(CONN_WIFI_DIRECT, "operation type invalid");
354 }
355
356 if (ret != SOFTBUS_OK) {
357 result.errorCode_ = ret;
358 operation->promise_.set_value(result);
359 }
360 }
361
HasPendingOperation()362 bool P2pEntity::HasPendingOperation()
363 {
364 std::lock_guard lock(pendingOperationLock_);
365 return !pendingOperations_.empty();
366 }
367
ClearPendingOperation()368 void P2pEntity::ClearPendingOperation()
369 {
370 std::lock_guard lock(pendingOperationLock_);
371 P2pOperationResult result;
372 result.errorCode_ = SOFTBUS_CONN_ENTITY_UNAVAILABLE;
373 while (!pendingOperations_.empty()) {
374 pendingOperations_.front()->promise_.set_value(result);
375 pendingOperations_.pop();
376 }
377 }
378
OnP2pStateChangeEvent(P2pState state)379 void P2pEntity::OnP2pStateChangeEvent(P2pState state)
380 {
381 std::lock_guard lock(operationLock_);
382 UpdateInterfaceManagerWhenStateChanged(state);
383 WifiDirectUtils::SyncLnnInfoForP2p(WIFI_DIRECT_ROLE_NONE, P2pAdapter::GetMacAddress(), "");
384 state_->OnP2pStateChangeEvent(state);
385 }
386
OnP2pConnectionChangeEvent(const WifiP2pLinkedInfo & info,const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> & groupInfo)387 void P2pEntity::OnP2pConnectionChangeEvent(
388 const WifiP2pLinkedInfo &info, const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> &groupInfo)
389 {
390 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
391 std::lock_guard lock(operationLock_);
392
393 if (info.connectState == P2pConnectionState::P2P_DISCONNECTED) {
394 currentFrequency_ = 0;
395 }
396
397 state_->PreprocessP2pConnectionChangeEvent(info, groupInfo);
398 UpdateInterfaceManager(info, groupInfo);
399 UpdateLinkManager(info, groupInfo);
400 state_->OnP2pConnectionChangeEvent(info, groupInfo);
401 }
402
ResetInterfaceInfo(const std::string & localMac)403 static void ResetInterfaceInfo(const std::string &localMac)
404 {
405 int listenModule = -1;
406 int listenPort = -1;
407 InterfaceManager::GetInstance().UpdateInterface(
408 InterfaceInfo::P2P, [&listenPort, &listenModule, localMac](InterfaceInfo &interface) {
409 listenPort = interface.GetP2pListenPort();
410 listenModule = interface.GetP2pListenModule();
411
412 interface.SetConnectedDeviceCount(0);
413 interface.SetRole(LinkInfo::LinkMode::NONE);
414 interface.SetReuseCount(0);
415 interface.SetP2pListenPort(0);
416 interface.SetSsid("");
417 interface.SetDynamicMac("");
418 interface.SetPsk("");
419 interface.SetCenter20M(0);
420 interface.SetIpString(Ipv4Info());
421 interface.SetP2pListenModule(-1);
422 interface.SetBaseMac(localMac);
423 return SOFTBUS_OK;
424 });
425 if (listenPort > 0) {
426 AuthNegotiateChannel::StopListening(AUTH_LINK_TYPE_P2P, static_cast<ListenerModule>(listenModule));
427 }
428 }
429
UpdateInterfaceInfo(const std::string & localMac,const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> & groupInfo)430 static void UpdateInterfaceInfo(
431 const std::string &localMac, const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> &groupInfo)
432 {
433 CONN_LOGI(CONN_WIFI_DIRECT, "isGroupOwner=%{public}d, clientDeviceSize=%{public}zu", groupInfo->isGroupOwner,
434 groupInfo->clientDevices.size());
435 std::string groupConfig;
436 if (groupInfo->isGroupOwner) {
437 auto ret = P2pAdapter::GetGroupConfig(groupConfig);
438 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_WIFI_DIRECT, "get group config failed, error=%d", ret);
439 }
440 std::string dynamicMac;
441 auto ret = P2pAdapter::GetDynamicMacAddress(dynamicMac);
442 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_WIFI_DIRECT, "get dynamic mac failed, error=%d", ret);
443 std::string ip;
444 ret = P2pAdapter::GetIpAddress(ip);
445 if (ret != SOFTBUS_OK) {
446 CONN_LOGE(CONN_WIFI_DIRECT, "get ip failed, error=%{public}d", ret);
447 } else {
448 CONN_LOGI(CONN_WIFI_DIRECT, "localIp=%{public}s", WifiDirectAnonymizeIp(ip).c_str());
449 }
450
451 InterfaceManager::GetInstance().UpdateInterface(
452 InterfaceInfo::P2P, [localMac, dynamicMac, ip, groupInfo, groupConfig](InterfaceInfo &interface) {
453 interface.SetBaseMac(localMac);
454 interface.SetDynamicMac(dynamicMac);
455 if (!ip.empty()) {
456 interface.SetIpString(Ipv4Info(ip));
457 }
458 interface.SetConnectedDeviceCount(groupInfo->clientDevices.size());
459 interface.SetRole(groupInfo->isGroupOwner ? LinkInfo::LinkMode::GO : LinkInfo::LinkMode::GC);
460 if (groupInfo->isGroupOwner) {
461 interface.SetP2pGroupConfig(groupConfig);
462 }
463 return SOFTBUS_OK;
464 });
465 }
466
UpdateInterfaceManager(const WifiP2pLinkedInfo & info,const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> & groupInfo)467 void P2pEntity::UpdateInterfaceManager(
468 const WifiP2pLinkedInfo &info, const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> &groupInfo)
469 {
470 auto localMac = P2pAdapter::GetMacAddress();
471 if (info.connectState == P2pConnectionState::P2P_DISCONNECTED || groupInfo == nullptr) {
472 ResetInterfaceInfo(localMac);
473 return;
474 }
475 CONN_LOGI(CONN_WIFI_DIRECT, "p2p has group, update p2p interface info");
476 UpdateInterfaceInfo(localMac, groupInfo);
477 }
478
UpdateInnerLink(const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> & groupInfo,const std::string & localMac)479 static void UpdateInnerLink(const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> &groupInfo,
480 const std::string &localMac)
481 {
482 auto frequency = groupInfo->frequency;
483 if (!groupInfo->isGroupOwner) {
484 CONN_LOGI(CONN_WIFI_DIRECT, "not group owner, groupOwnerMac=%{public}s",
485 WifiDirectAnonymizeMac(groupInfo->groupOwner.address).c_str());
486 LinkManager::GetInstance().ProcessIfPresent(groupInfo->groupOwner.address, [frequency, groupInfo, localMac]
487 (InnerLink &link) {
488 link.SetState(InnerLink::LinkState::CONNECTED);
489 link.SetFrequency(frequency);
490 link.SetRemoteDynamicMac(groupInfo->groupOwner.randomMac);
491 link.SetLocalDynamicMac(localMac);
492 });
493 return;
494 }
495 std::string ip;
496 InterfaceManager::GetInstance().ReadInterface(InterfaceInfo::P2P, [&ip](const InterfaceInfo &interface) {
497 ip = interface.GetIpString().ToIpString();
498 return SOFTBUS_OK;
499 });
500 for (const auto &client : groupInfo->clientDevices) {
501 CONN_LOGI(CONN_WIFI_DIRECT, "remoteMac=%{public}s", WifiDirectAnonymizeMac(client.address).c_str());
502 LinkManager::GetInstance().ProcessIfPresent(client.address, [ip, frequency, client, localMac](InnerLink &link) {
503 link.SetState(InnerLink::LinkState::CONNECTED);
504 link.SetFrequency(frequency);
505 link.SetLocalIpv4(ip);
506 link.SetRemoteDynamicMac(client.randomMac);
507 link.SetLocalDynamicMac(localMac);
508 });
509 }
510 std::vector<std::string> invalidLinks;
511 auto clients = groupInfo->clientDevices;
512 LinkManager::GetInstance().ForEach([&invalidLinks, clients](const InnerLink &link) {
513 if (link.GetLinkType() != InnerLink::LinkType::P2P) {
514 return false;
515 }
516 if (link.GetState() == InnerLink::LinkState::CONNECTING) {
517 return false;
518 }
519 if (std::none_of(clients.begin(), clients.end(), [&link](const P2pAdapter::WifiDirectP2pDeviceInfo &item) {
520 return item.address == link.GetRemoteBaseMac();
521 })) {
522 invalidLinks.push_back(link.GetRemoteDeviceId());
523 }
524 // return false to range all link
525 return false;
526 });
527 for (const auto &remoteDeviceId : invalidLinks) {
528 LinkManager::GetInstance().RemoveLink(InnerLink::LinkType::P2P, remoteDeviceId);
529 }
530 }
531
UpdateLinkManager(const WifiP2pLinkedInfo & info,const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> & groupInfo)532 void P2pEntity::UpdateLinkManager(
533 const WifiP2pLinkedInfo &info, const std::shared_ptr<P2pAdapter::WifiDirectP2pGroupInfo> &groupInfo)
534 {
535 if (info.connectState == P2pConnectionState::P2P_DISCONNECTED) {
536 LinkManager::GetInstance().RemoveLinks(InnerLink::LinkType::P2P);
537 return;
538 }
539 CONN_CHECK_AND_RETURN_LOGE(groupInfo, CONN_WIFI_DIRECT, "groupInfo is null");
540 std::string dynamicMac;
541 auto ret = P2pAdapter::GetDynamicMacAddress(dynamicMac);
542 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_WIFI_DIRECT, "get dynamic mac failed, error=%{public}d", ret);
543 UpdateInnerLink(groupInfo, dynamicMac);
544 }
545
UpdateInterfaceManagerWhenStateChanged(P2pState state)546 void P2pEntity::UpdateInterfaceManagerWhenStateChanged(P2pState state)
547 {
548 bool enable;
549 std::string localMac;
550 if (state != P2pState::P2P_STATE_STARTED) {
551 enable = false;
552 } else {
553 localMac = P2pAdapter::GetMacAddress();
554 enable = true;
555 }
556
557 InterfaceManager::GetInstance().UpdateInterface(InterfaceInfo::P2P, [enable, localMac](InterfaceInfo &interface) {
558 interface.SetIsEnable(enable);
559 interface.SetBaseMac(localMac);
560 if (!enable) {
561 interface.SetIpString(Ipv4Info());
562 }
563 return SOFTBUS_OK;
564 });
565 }
566
567 } // namespace OHOS::SoftBus
568