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 &param)
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 &param)
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 &param)
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 &param)
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 &param)
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