1 /*
2  * Copyright (C) 2021-2022 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 "p2p_state_machine.h"
17 #include <cerrno>
18 #include <ifaddrs.h>
19 #include <net/if.h>
20 #include <string>
21 #include <functional>
22 #include <map>
23 #include "dhcpd_interface.h"
24 #include "ip_tools.h"
25 #include "ipv4_address.h"
26 #include "wifi_global_func.h"
27 #include "wifi_logger.h"
28 #include "wifi_net_agent.h"
29 #include "wifi_p2p_dns_sd_service_info.h"
30 #include "wifi_p2p_dns_sd_service_response.h"
31 #include "wifi_p2p_hal_interface.h"
32 #include "wifi_p2p_upnp_service_response.h"
33 #include "wifi_config_center.h"
34 #include "wifi_hisysevent.h"
35 #include "wifi_common_util.h"
36 #include "arp_checker.h"
37 #include "mac_address.h"
38 
39 DEFINE_WIFILOG_P2P_LABEL("P2pStateMachine");
40 #define P2P_PREFIX_LEN 4
41 
42 namespace OHOS {
43 namespace Wifi {
44 const std::string DEFAULT_P2P_IPADDR = "192.168.49.1";
45 //miracast
46 const int CMD_TYPE_SET = 2;
47 const int DATA_TYPE_P2P_BUSINESS = 1;
48 const int ARP_TIMEOUT = 100;
49 const std::string CARRY_DATA_MIRACAST = "1";
50 const std::string PRIMARY_PC_TYPE = "1";
51 const std::string PRIMARY_DISPLAY_TYPE = "7";
52 std::mutex P2pStateMachine::m_gcJoinmutex;
53 
54 DHCPTYPE P2pStateMachine::m_isNeedDhcp = DHCPTYPE::DHCP_P2P;
P2pStateMachine(P2pMonitor & monitor,WifiP2pGroupManager & groupMgr,WifiP2pDeviceManager & setDeviceMgr,WifiP2pServiceManager & setSvrMgr,AuthorizingNegotiationRequestState & authorizingNegotiationRequestState,GroupFormedState & groupFormedState,GroupNegotiationState & groupNegotiationState,InvitationReceivedState & invltationRecelvedState,InvitationRequestState & invitationRequestState,P2pDefaultState & defaultState,P2pDisabledState & disabledState,P2pDisablingState & disablingState,P2pEnabledState & enabledState,P2pEnablingState & enablingState,P2pGroupFormationState & groupFormationState,P2pGroupJoinState & groupJoinState,P2pGroupOperatingState & groupOperatingState,P2pIdleState & idleState,P2pInvitingState & invitingState,ProvisionDiscoveryState & provisionDiscoveryState,P2pGroupRemoveState & groupRemoveState)55 P2pStateMachine::P2pStateMachine(P2pMonitor &monitor, WifiP2pGroupManager &groupMgr,
56     WifiP2pDeviceManager &setDeviceMgr,
57     WifiP2pServiceManager &setSvrMgr, AuthorizingNegotiationRequestState &authorizingNegotiationRequestState,
58     GroupFormedState &groupFormedState, GroupNegotiationState &groupNegotiationState,
59     InvitationReceivedState &invltationRecelvedState, InvitationRequestState &invitationRequestState,
60     P2pDefaultState &defaultState, P2pDisabledState &disabledState, P2pDisablingState &disablingState,
61     P2pEnabledState &enabledState, P2pEnablingState &enablingState,
62     P2pGroupFormationState &groupFormationState, P2pGroupJoinState &groupJoinState,
63     P2pGroupOperatingState &groupOperatingState, P2pIdleState &idleState, P2pInvitingState &invitingState,
64     ProvisionDiscoveryState &provisionDiscoveryState, P2pGroupRemoveState &groupRemoveState)
65     : StateMachine("P2pStateMachine"),
66       p2pServiceCallbacks(), p2pIface(), savedP2pConfig(),
67       p2pMonitor(monitor),
68       groupManager(groupMgr),
69       deviceManager(setDeviceMgr),
70       serviceManager(setSvrMgr),
71       p2pAuthorizingNegotiationRequestState(authorizingNegotiationRequestState),
72       p2pGroupFormedState(groupFormedState),
73       p2pGroupNegotiationState(groupNegotiationState),
74       p2pInvitationReceivedState(invltationRecelvedState),
75       p2pInvitationRequestState(invitationRequestState),
76       p2pDefaultState(defaultState),
77       p2pDisabledState(disabledState),
78       p2pDisablingState(disablingState),
79       p2pEnabledState(enabledState),
80       p2pEnablingState(enablingState),
81       p2pGroupFormationState(groupFormationState),
82       p2pGroupJoinState(groupJoinState),
83       p2pGroupOperatingState(groupOperatingState),
84       p2pIdleState(idleState),
85       p2pInvitingState(invitingState),
86       p2pProvisionDiscoveryState(provisionDiscoveryState),
87       p2pGroupRemoveState(groupRemoveState),
88       p2pDevIface()
89 {
90     Initialize();
91 }
92 
~P2pStateMachine()93 P2pStateMachine::~P2pStateMachine()
94 {
95     StopHandlerThread();
96     groupManager.StashGroups();
97     StopDhcpClient(groupManager.GetCurrentGroup().GetInterface().c_str(), false);
98     StopP2pDhcpClient();
99     StopDhcpServer();
100     if (pDhcpResultNotify != nullptr) {
101         delete pDhcpResultNotify;
102         pDhcpResultNotify = nullptr;
103     }
104     AbstractUI::GetInstance().UnInit();
105 }
106 
Initialize()107 void P2pStateMachine::Initialize()
108 {
109     if (!InitialStateMachine("P2pStateMachine")) {
110         WIFI_LOGE("P2P StateMachine Initialize failed.");
111         return;
112     }
113 
114     groupManager.Initialize();
115 
116     /**
117      * Initialize the UI server in advance.
118      */
119     AbstractUI::GetInstance();
120     StatePlus(&p2pDefaultState, nullptr);
121     StatePlus(&p2pDisabledState, &p2pDefaultState);
122     StatePlus(&p2pDisablingState, &p2pDefaultState);
123     StatePlus(&p2pEnablingState, &p2pDefaultState);
124     StatePlus(&p2pEnabledState, &p2pDefaultState);
125     StatePlus(&p2pIdleState, &p2pEnabledState);
126     StatePlus(&p2pGroupJoinState, &p2pEnabledState);
127     StatePlus(&p2pGroupOperatingState, &p2pEnabledState);
128     StatePlus(&p2pInvitingState, &p2pEnabledState);
129     StatePlus(&p2pInvitationRequestState, &p2pInvitingState);
130     StatePlus(&p2pInvitationReceivedState, &p2pInvitingState);
131 
132     StatePlus(&p2pGroupFormationState, &p2pEnabledState);
133     StatePlus(&p2pGroupNegotiationState, &p2pGroupFormationState);
134     StatePlus(&p2pAuthorizingNegotiationRequestState, &p2pGroupFormationState);
135     StatePlus(&p2pProvisionDiscoveryState, &p2pGroupFormationState);
136     StatePlus(&p2pGroupFormedState, &p2pGroupFormationState);
137     StatePlus(&p2pGroupRemoveState, &p2pGroupOperatingState);
138 
139     SetFirstState(&p2pDisabledState);
140     StartStateMachine();
141     pDhcpResultNotify = new (std::nothrow)DhcpResultNotify();
142     if (pDhcpResultNotify == nullptr) {
143         WIFI_LOGW("pDhcpResultNotify Initialize failed.");
144     }
145     return;
146 }
147 
RegisterEventHandler()148 void P2pStateMachine::RegisterEventHandler()
149 {
150     using namespace std::placeholders;
151     using type = void (StateMachine::*)(int, int, int, const std::any &);
152 
153     auto handler = std::bind(static_cast<type>(&StateMachine::SendMessage), this, _1, _2, _3, _4);
154 
155     p2pMonitor.RegisterIfaceHandler(
156         p2pIface, [=](P2P_STATE_MACHINE_CMD msgName, int param1, int param2, const std::any &messageObj) {
157             handler(static_cast<int>(msgName), param1, param2, messageObj);
158         });
159 }
160 
UpdateOwnDevice(P2pDeviceStatus status)161 void P2pStateMachine::UpdateOwnDevice(P2pDeviceStatus status)
162 {
163     deviceManager.GetThisDevice().SetP2pDeviceStatus(status);
164     BroadcastThisDeviceChanaged(deviceManager.GetThisDevice());
165 }
166 
InitializeThisDevice()167 void P2pStateMachine::InitializeThisDevice()
168 {
169     std::string deviceName;
170     constexpr size_t randomLen = 4;
171     P2pVendorConfig p2pVendorCfg;
172     int ret = WifiSettings::GetInstance().GetP2pVendorConfig(p2pVendorCfg);
173     if (ret < 0) {
174         WIFI_LOGW("Failed to obtain P2pVendorConfig information.");
175     }
176     WIFI_LOGI("%{public}s: random mac is %{public}s", __func__, p2pVendorCfg.GetRandomMacSupport() ? "true" : "false");
177     if (p2pVendorCfg.GetDeviceName().empty()) {
178         deviceName = std::string("OHOS_") + GetRandomStr(randomLen);
179         p2pVendorCfg.SetDeviceName(deviceName);
180         ret = WifiSettings::GetInstance().SetP2pVendorConfig(p2pVendorCfg);
181         if (ret < 0) {
182             WIFI_LOGW("Failed to Set P2pVendorConfig information.");
183         }
184     } else {
185         deviceName = p2pVendorCfg.GetDeviceName();
186     }
187     deviceManager.GetThisDevice().SetDeviceName(deviceName);
188     deviceManager.GetThisDevice().SetPrimaryDeviceType(p2pVendorCfg.GetPrimaryDeviceType());
189     deviceManager.GetThisDevice().SetSecondaryDeviceType(p2pVendorCfg.GetSecondaryDeviceType());
190 }
191 
UpdateGroupManager() const192 void P2pStateMachine::UpdateGroupManager() const
193 {
194     std::map<int, WifiP2pGroupInfo> wpaGroups;
195     WifiErrorNo retCode = WifiP2PHalInterface::GetInstance().ListNetworks(wpaGroups);
196     if (retCode == WifiErrorNo::WIFI_HAL_OPT_FAILED) {
197         WIFI_LOGE("Failed to get listNetworks");
198         return;
199     }
200     for (auto wpaGroup = wpaGroups.begin(); wpaGroup != wpaGroups.end(); ++wpaGroup) {
201         groupManager.UpdateWpaGroup(wpaGroup->second);
202     }
203     groupManager.UpdateGroupsNetwork(wpaGroups);
204 }
205 
UpdatePersistentGroups() const206 void P2pStateMachine::UpdatePersistentGroups() const
207 {
208     WIFI_LOGI("UpdatePersistentGroups");
209     std::vector<WifiP2pGroupInfo> groups;
210     groups = groupManager.GetGroups();
211     WifiSettings::GetInstance().SetWifiP2pGroupInfo(groups);
212     WifiSettings::GetInstance().SyncWifiP2pGroupInfoConfig();
213     BroadcastPersistentGroupsChanged();
214 }
215 
CheckIsDisplayDevice(const std::string & mac) const216 bool P2pStateMachine::CheckIsDisplayDevice(const std::string &mac) const
217 {
218     WifiP2pDevice dev = deviceManager.GetDevices(mac);
219     std::string primaryType = dev.GetPrimaryDeviceType();
220     std::vector<std::string> type = StrSplit(primaryType, "-");
221     if (!type.empty() && (type[0] == PRIMARY_PC_TYPE || type[0] == PRIMARY_DISPLAY_TYPE)) {
222         WIFI_LOGI("peer is a dispaly type");
223         return true;
224     }
225     return false;
226 }
227 
ReawakenPersistentGroup(WifiP2pConfigInternal & config) const228 bool P2pStateMachine::ReawakenPersistentGroup(WifiP2pConfigInternal &config) const
229 {
230     const WifiP2pDevice device = FetchNewerDeviceInfo(config.GetDeviceAddress());
231     if (!device.IsValid()) {
232         WIFI_LOGE("Invalid device.");
233         return false;
234     }
235 
236     bool isJoin = device.IsGroupOwner();
237     std::string groupName = config.GetGroupName();
238     if (isJoin && !device.IsGroupLimit()) {
239         if (groupName.empty()) {
240             groupName = device.GetNetworkName();
241         }
242         int networkId = groupManager.GetGroupNetworkId(device, groupName);
243         if (networkId >= 0) {
244             /**
245              * If GO is running on the peer device and the GO has been connected,
246              * you can directly connect to the peer device through p2p_group_add.
247              */
248             if (CheckIsDisplayDevice(config.GetDeviceAddress()) && !groupManager.IsOldPersistentGroup(networkId)) {
249                 WifiP2PHalInterface::GetInstance().RemoveNetwork(networkId);
250                 return false;
251             }
252             if (WifiErrorNo::WIFI_HAL_OPT_OK != WifiP2PHalInterface::GetInstance().GroupAdd(true, networkId, 0)) {
253                 return false;
254             }
255             return true;
256         }
257     }
258 
259     if (!isJoin && device.IsDeviceLimit()) {
260         return false;
261     }
262 
263     if (!isJoin && device.Isinviteable()) {
264         /**
265          * If the peer device is in idle state and the local device is in idle state,
266          * try to connect to the peer device in revoke mode.
267          */
268         int networkId = -1;
269         /* Prepare to reinvoke as GC. */
270         if (config.GetNetId() >= 0) {
271             if (config.GetDeviceAddress() == groupManager.GetGroupOwnerAddr(config.GetNetId())) {
272                 networkId = config.GetNetId();
273             }
274         } else {
275             networkId = groupManager.GetGroupNetworkId(device);
276         }
277         if (networkId < 0) {
278             WIFI_LOGI("cannot find device from gc devices");
279             /**
280              * Prepare to reinvoke as GO.
281              * Mean that the group is not found when the peer device roles as GO,
282              * try to find the group that this device roles as GO and the peer device roles as GC.
283              */
284             networkId = groupManager.GetNetworkIdFromClients(device);
285         }
286 
287         if (networkId >= 0) {
288             /**
289              * If a persistent group that has been connected to the peer device exists,
290              * the reinvoke process is triggered.
291              */
292             return ReinvokeGroup(config, networkId, device);
293         } else {
294             config.SetNetId(networkId);
295         }
296     }
297 
298     return false;
299 }
300 
ReinvokeGroup(WifiP2pConfigInternal & config,int networkId,const WifiP2pDevice & device) const301 bool P2pStateMachine::ReinvokeGroup(WifiP2pConfigInternal &config, int networkId,
302     const WifiP2pDevice &device) const
303 {
304     if (WifiErrorNo::WIFI_HAL_OPT_OK !=
305         WifiP2PHalInterface::GetInstance().Reinvoke(networkId, device.GetDeviceAddress())) {
306         WIFI_LOGE("Failed to reinvoke.");
307         UpdateGroupManager();
308         UpdatePersistentGroups();
309         return false;
310     } else {
311         config.SetNetId(networkId);
312         return true;
313     }
314 }
315 
FetchNewerDeviceInfo(const std::string & deviceAddr) const316 WifiP2pDevice P2pStateMachine::FetchNewerDeviceInfo(const std::string &deviceAddr) const
317 {
318     WifiP2pDevice device;
319     device.SetDeviceAddress(deviceAddr);
320     if (deviceAddr.empty()) {
321         WIFI_LOGE("Invalid device address.");
322         return device;
323     }
324     WifiP2pDevice newDevice = deviceManager.GetDevices(deviceAddr);
325     if (WifiP2PHalInterface::GetInstance().GetP2pPeer(deviceAddr, device) ==
326         WifiErrorNo::WIFI_HAL_OPT_OK) {
327         int groupCap = device.GetGroupCapabilitys();
328         deviceManager.UpdateDeviceGroupCap(deviceAddr, groupCap);
329         newDevice.SetGroupCapabilitys(groupCap);
330         newDevice.SetDeviceCapabilitys(device.GetDeviceCapabilitys());
331         newDevice.SetNetworkName(device.GetNetworkName());
332     }
333     return newDevice;
334 }
335 
DealGroupCreationFailed()336 void P2pStateMachine::DealGroupCreationFailed()
337 {
338     WifiP2pLinkedInfo info;
339     info.SetConnectState(P2pConnectedState::P2P_DISCONNECTED);
340     WifiConfigCenter::GetInstance().SaveP2pInfo(info);
341     groupManager.SaveP2pInfo(info);
342     BroadcastP2pConnectionChanged();
343 
344     if (!savedP2pConfig.GetDeviceAddress().empty() && deviceManager.RemoveDevice(savedP2pConfig.GetDeviceAddress())) {
345         BroadcastP2pPeersChanged();
346     }
347     WifiErrorNo ret = WifiP2PHalInterface::GetInstance().P2pFlush();
348     if (ret != WifiErrorNo::WIFI_HAL_OPT_OK) {
349         WIFI_LOGE("call P2pFlush() failed, ErrCode: %{public}d", static_cast<int>(ret));
350     }
351     SendMessage(static_cast<int>(P2P_STATE_MACHINE_CMD::CMD_DEVICE_DISCOVERS));
352 }
353 
RemoveGroupByNetworkId(int networkId) const354 void P2pStateMachine::RemoveGroupByNetworkId(int networkId) const
355 {
356     if (WifiP2PHalInterface::GetInstance().RemoveNetwork(networkId) != WifiErrorNo::WIFI_HAL_OPT_OK) {
357         WIFI_LOGE("failed to remove networkId, networkId is %{public}d.", networkId);
358     }
359     UpdateGroupManager();
360     UpdatePersistentGroups();
361     BroadcastPersistentGroupsChanged();
362 }
363 
SetWifiP2pInfoWhenGroupFormed(const std::string & groupOwnerAddress)364 void P2pStateMachine::SetWifiP2pInfoWhenGroupFormed(const std::string &groupOwnerAddress)
365 {
366     WifiP2pLinkedInfo p2pInfo;
367     WifiConfigCenter::GetInstance().GetP2pInfo(p2pInfo);
368     p2pInfo.SetIsGroupOwner(groupManager.GetCurrentGroup().IsGroupOwner());
369     p2pInfo.SetIsGroupOwnerAddress(groupOwnerAddress);
370     WifiConfigCenter::GetInstance().SaveP2pInfo(p2pInfo);
371     groupManager.SaveP2pInfo(p2pInfo);
372 }
373 
AddClientInfo(std::vector<GcInfo> & gcInfos)374 ErrCode P2pStateMachine::AddClientInfo(std::vector<GcInfo> &gcInfos)
375 {
376     std::lock_guard<std::mutex> lock(m_gcJoinmutex);
377     WifiP2pGroupInfo groupInfo = groupManager.GetCurrentGroup();
378     if (!groupInfo.IsGroupOwner()) {
379         return ErrCode::WIFI_OPT_FAILED;
380     }
381     std::vector<OHOS::Wifi::WifiP2pDevice> deviceList;
382     if (deviceManager.GetDevicesList(deviceList) <= 0) {
383         WIFI_LOGE("deviceList.size <=0 ");
384         return WIFI_OPT_FAILED;
385     }
386     WifiP2pDevice curDev;
387     GcInfo curGc;
388     bool isFound = false;
389     for (auto iterClientList : curClientList) {
390         for (auto iterDeviceList : deviceList) {
391             if (iterDeviceList.GetDeviceAddress() == iterClientList) {
392                 curDev = iterDeviceList;
393                 auto p2pDeviceMac = curDev.GetDeviceAddress();
394                 auto p2pGroupMac = curDev.GetGroupAddress();
395                 curGc = MatchDevInGcInfos(p2pDeviceMac, p2pGroupMac, gcInfos);
396                 isFound = !(curGc.ip.empty());
397                 break;
398             }
399         }
400         if (isFound) {
401             break;
402         }
403     }
404     if (!isFound) {
405         return ErrCode::WIFI_OPT_FAILED;
406     } else {
407         auto iter = std::find(curClientList.begin(), curClientList.end(), curDev.GetDeviceAddress().c_str());
408         curClientList.erase(iter);
409     }
410     WifiP2pLinkedInfo linkedInfo;
411     WifiConfigCenter::GetInstance().GetP2pInfo(linkedInfo);
412     linkedInfo.ClearClientInfo();
413     linkedInfo.AddClientInfoList(curGc.mac, curGc.ip, curDev.GetDeviceName());
414 
415     if (WifiConfigCenter::GetInstance().SaveP2pInfo(linkedInfo) == 0) {
416         groupManager.SaveP2pInfo(linkedInfo);
417         BroadcastP2pGcJoinGroup(curGc);
418         return ErrCode::WIFI_OPT_SUCCESS;
419     }
420     return ErrCode::WIFI_OPT_FAILED;
421 }
422 
MatchDevInGcInfos(const std::string & deviceAddr,const std::string & groupAddr,std::vector<GcInfo> & gcInfos)423 GcInfo P2pStateMachine::MatchDevInGcInfos(const std::string &deviceAddr,
424     const std::string &groupAddr, std::vector<GcInfo> &gcInfos)
425 {
426     WIFI_LOGD("P2pStateMachine::MatchDevInGcInfos: devAddr = %s, groupAddr = %s",
427         MacAnonymize(deviceAddr).c_str(), MacAnonymize(groupAddr).c_str());
428     GcInfo info;
429     for (auto gcInfo : gcInfos) {
430         if ((gcInfo.mac == deviceAddr) || (gcInfo.mac == groupAddr)) {
431             WIFI_LOGD("find curDev Ip:%s", gcInfo.ip.c_str());
432             info = gcInfo;
433             break;
434         }
435     }
436     return info;
437 }
438 
RemoveClientInfo(std::string mac)439 ErrCode P2pStateMachine::RemoveClientInfo(std::string mac)
440 {
441     WIFI_LOGD("P2pStateMachine::RemoveClientInfo: mac = %s",
442         MacAnonymize(mac).c_str());
443     WifiP2pLinkedInfo linkedInfo;
444     WifiConfigCenter::GetInstance().GetP2pInfo(linkedInfo);
445     linkedInfo.RemoveClientInfo(mac);
446     if (WifiConfigCenter::GetInstance().SaveP2pInfo(linkedInfo) == 0) {
447         groupManager.SaveP2pInfo(linkedInfo);
448         return ErrCode::WIFI_OPT_SUCCESS;
449     }
450     return ErrCode::WIFI_OPT_FAILED;
451 }
452 
BroadcastP2pStatusChanged(P2pState state) const453 void P2pStateMachine::BroadcastP2pStatusChanged(P2pState state) const
454 {
455     WifiConfigCenter::GetInstance().SetP2pState(static_cast<int>(state));
456     std::unique_lock<std::mutex> lock(cbMapMutex);
457     for (const auto &callBackItem : p2pServiceCallbacks) {
458         if (callBackItem.second.OnP2pStateChangedEvent != nullptr) {
459             callBackItem.second.OnP2pStateChangedEvent(state);
460         }
461     }
462 }
463 
BroadcastP2pPeersChanged() const464 void P2pStateMachine::BroadcastP2pPeersChanged() const
465 {
466     std::vector<WifiP2pDevice> peers;
467     deviceManager.GetDevicesList(peers);
468     std::unique_lock<std::mutex> lock(cbMapMutex);
469     for (const auto &callBackItem : p2pServiceCallbacks) {
470         if (callBackItem.second.OnP2pPeersChangedEvent != nullptr) {
471             callBackItem.second.OnP2pPeersChangedEvent(peers);
472         }
473     }
474 }
475 
BroadcastP2pPrivatePeersChanged(std::string & privateInfo) const476 void P2pStateMachine::BroadcastP2pPrivatePeersChanged(std::string &privateInfo) const
477 {
478     std::unique_lock<std::mutex> lock(cbMapMutex);
479     for (const auto &callBackItem : p2pServiceCallbacks) {
480         if (callBackItem.second.OnP2pPrivatePeersChangedEvent != nullptr) {
481             callBackItem.second.OnP2pPrivatePeersChangedEvent(privateInfo);
482         }
483     }
484 }
485 
BroadcastP2pServicesChanged() const486 void P2pStateMachine::BroadcastP2pServicesChanged() const
487 {
488     std::vector<WifiP2pServiceInfo> svrInfoList;
489     serviceManager.GetDeviceServices(svrInfoList);
490     std::unique_lock<std::mutex> lock(cbMapMutex);
491     for (const auto &callBackItem : p2pServiceCallbacks) {
492         if (callBackItem.second.OnP2pServicesChangedEvent != nullptr) {
493             callBackItem.second.OnP2pServicesChangedEvent(svrInfoList);
494         }
495     }
496 }
497 
BroadcastP2pConnectionChanged() const498 void P2pStateMachine::BroadcastP2pConnectionChanged() const
499 {
500     WifiP2pLinkedInfo p2pInfo;
501     WifiConfigCenter::GetInstance().GetP2pInfo(p2pInfo);
502     std::unique_lock<std::mutex> lock(cbMapMutex);
503     for (const auto &callBackItem : p2pServiceCallbacks) {
504         if (callBackItem.second.OnP2pConnectionChangedEvent != nullptr) {
505             callBackItem.second.OnP2pConnectionChangedEvent(p2pInfo);
506         }
507     }
508 }
509 
BroadcastThisDeviceChanaged(const WifiP2pDevice & device) const510 void P2pStateMachine::BroadcastThisDeviceChanaged(const WifiP2pDevice &device) const
511 {
512     std::unique_lock<std::mutex> lock(cbMapMutex);
513     for (const auto &callBackItem : p2pServiceCallbacks) {
514         if (callBackItem.second.OnP2pThisDeviceChangedEvent != nullptr) {
515             callBackItem.second.OnP2pThisDeviceChangedEvent(device);
516         }
517     }
518 }
519 
BroadcastP2pDiscoveryChanged(bool isActive) const520 void P2pStateMachine::BroadcastP2pDiscoveryChanged(bool isActive) const
521 {
522     int status = isActive ? 1 : 0;
523     WifiConfigCenter::GetInstance().SetP2pDiscoverState(status);
524     std::unique_lock<std::mutex> lock(cbMapMutex);
525     for (const auto &callBackItem : p2pServiceCallbacks) {
526         if (callBackItem.second.OnP2pDiscoveryChangedEvent != nullptr) {
527             callBackItem.second.OnP2pDiscoveryChangedEvent(isActive);
528         }
529     }
530 }
531 
BroadcastP2pGcJoinGroup(GcInfo & info) const532 void P2pStateMachine::BroadcastP2pGcJoinGroup(GcInfo &info) const
533 {
534     for (const auto &callBackItem : p2pServiceCallbacks) {
535         if (callBackItem.second.OnP2pGcJoinGroupEvent) {
536             callBackItem.second.OnP2pGcJoinGroupEvent(info);
537         }
538     }
539 }
540 
BroadcastP2pGcLeaveGroup(WifiP2pDevice & device) const541 void P2pStateMachine::BroadcastP2pGcLeaveGroup(WifiP2pDevice &device) const
542 {
543     WifiP2pLinkedInfo p2pInfo;
544     WifiConfigCenter::GetInstance().GetP2pInfo(p2pInfo);
545     auto gcInfos = p2pInfo.GetClientInfoList();
546     GcInfo curGcInfo;
547     for (auto gcInfo : gcInfos) {
548         if (device.GetDeviceAddress() == gcInfo.mac) {
549             curGcInfo = gcInfo;
550         }
551     }
552     for (const auto &callBackItem : p2pServiceCallbacks) {
553         if (callBackItem.second.OnP2pGcLeaveGroupEvent) {
554             callBackItem.second.OnP2pGcLeaveGroupEvent(curGcInfo);
555         }
556     }
557 }
558 
BroadcastPersistentGroupsChanged() const559 void P2pStateMachine::BroadcastPersistentGroupsChanged() const
560 {
561     std::unique_lock<std::mutex> lock(cbMapMutex);
562     for (const auto &callBackItem : p2pServiceCallbacks) {
563         if (callBackItem.second.OnP2pGroupsChangedEvent != nullptr) {
564             callBackItem.second.OnP2pGroupsChangedEvent();
565         }
566     }
567 }
568 
BroadcastActionResult(P2pActionCallback action,ErrCode result) const569 void P2pStateMachine::BroadcastActionResult(P2pActionCallback action, ErrCode result) const
570 {
571     std::unique_lock<std::mutex> lock(cbMapMutex);
572     for (const auto &callBackItem : p2pServiceCallbacks) {
573         if (callBackItem.second.OnP2pActionResultEvent != nullptr) {
574             callBackItem.second.OnP2pActionResultEvent(action, result);
575         }
576     }
577 }
578 
BroadcastServiceResult(P2pServicerProtocolType serviceType,const std::vector<unsigned char> & respData,const WifiP2pDevice & srcDevice) const579 void P2pStateMachine::BroadcastServiceResult(P2pServicerProtocolType serviceType,
580     const std::vector<unsigned char> &respData, const WifiP2pDevice &srcDevice) const
581 {
582     std::unique_lock<std::mutex> lock(cbMapMutex);
583     for (const auto &callBackItem : p2pServiceCallbacks) {
584         if (callBackItem.second.OnP2pServiceAvailable != nullptr) {
585             callBackItem.second.OnP2pServiceAvailable(serviceType, respData, srcDevice);
586         }
587     }
588 }
589 
BroadcastDnsSdServiceResult(const std::string & instName,const std::string & regType,const WifiP2pDevice & srcDevice) const590 void P2pStateMachine::BroadcastDnsSdServiceResult(
591     const std::string &instName, const std::string &regType, const WifiP2pDevice &srcDevice) const
592 {
593     std::unique_lock<std::mutex> lock(cbMapMutex);
594     for (const auto &callBackItem : p2pServiceCallbacks) {
595         if (callBackItem.second.OnP2pDnsSdServiceAvailable != nullptr) {
596             callBackItem.second.OnP2pDnsSdServiceAvailable(instName, regType, srcDevice);
597         }
598     }
599 }
600 
BroadcastDnsSdTxtRecordResult(const std::string & wholeDomainName,const std::map<std::string,std::string> & txtMap,const WifiP2pDevice & srcDevice) const601 void P2pStateMachine::BroadcastDnsSdTxtRecordResult(const std::string &wholeDomainName,
602     const std::map<std::string, std::string> &txtMap, const WifiP2pDevice &srcDevice) const
603 {
604     std::unique_lock<std::mutex> lock(cbMapMutex);
605     for (const auto &callBackItem : p2pServiceCallbacks) {
606         if (callBackItem.second.OnP2pDnsSdTxtRecordAvailable != nullptr) {
607             callBackItem.second.OnP2pDnsSdTxtRecordAvailable(wholeDomainName, txtMap, srcDevice);
608         }
609     }
610 }
611 
BroadcastUpnpServiceResult(const std::vector<std::string> & uniqueServiceNames,const WifiP2pDevice & srcDevice) const612 void P2pStateMachine::BroadcastUpnpServiceResult(
613     const std::vector<std::string> &uniqueServiceNames, const WifiP2pDevice &srcDevice) const
614 {
615     std::unique_lock<std::mutex> lock(cbMapMutex);
616     for (const auto &callBackItem : p2pServiceCallbacks) {
617         if (callBackItem.second.OnP2pUpnpServiceAvailable != nullptr) {
618             callBackItem.second.OnP2pUpnpServiceAvailable(uniqueServiceNames, srcDevice);
619         }
620     }
621 }
622 
RegisterP2pServiceCallbacks(const IP2pServiceCallbacks & callback)623 void P2pStateMachine::RegisterP2pServiceCallbacks(const IP2pServiceCallbacks &callback)
624 {
625     WIFI_LOGI("RegisterP2pServiceCallbacks, callback module name: %{public}s", callback.callbackModuleName.c_str());
626     std::unique_lock<std::mutex> lock(cbMapMutex);
627     p2pServiceCallbacks.insert_or_assign(callback.callbackModuleName, callback);
628 }
629 
UnRegisterP2pServiceCallbacks(const IP2pServiceCallbacks & callback)630 void P2pStateMachine::UnRegisterP2pServiceCallbacks(const IP2pServiceCallbacks &callback)
631 {
632     WIFI_LOGI("UnRegisterP2pServiceCallbacks, callback module name: %{public}s", callback.callbackModuleName.c_str());
633     std::unique_lock<std::mutex> lock(cbMapMutex);
634     p2pServiceCallbacks.erase(callback.callbackModuleName);
635 }
636 
ClearAllP2pServiceCallbacks()637 void P2pStateMachine::ClearAllP2pServiceCallbacks()
638 {
639     WIFI_LOGI("ClearAllP2pServiceCallbacks");
640     std::unique_lock<std::mutex> lock(cbMapMutex);
641     p2pServiceCallbacks.clear();
642 }
643 
IsUsableGroupName(std::string nwName)644 bool P2pStateMachine::IsUsableGroupName(std::string nwName)
645 {
646     if (nwName.empty()) {
647         return false;
648     }
649     if (nwName.length() < MIN_GROUP_NAME_LENGTH || nwName.length() > MAX_GROUP_NAME_LENGTH) {
650         return false;
651     }
652     return true;
653 }
654 
IsConfigUnusable(const WifiP2pConfigInternal & config)655 P2pConfigErrCode P2pStateMachine::IsConfigUnusable(const WifiP2pConfigInternal &config)
656 {
657     constexpr unsigned NETWORK_NAME_MAX_LENGTH = 32;
658     constexpr int GROUP_OWNER_MAX_INTENT = 15;
659     if (config.GetDeviceAddress().empty()) {
660         WIFI_LOGE("P2pStateMachine::IsConfigUnusable: address is empty");
661         return P2pConfigErrCode::MAC_EMPTY;
662     }
663     if (!MacAddress::IsValidMac(config.GetDeviceAddress().c_str())) {
664         WIFI_LOGE("P2pStateMachine::IsConfigUnusable: invalid mac address");
665         return P2pConfigErrCode::ERR_MAC_FORMAT;
666     }
667     WifiP2pDevice device = deviceManager.GetDevices(config.GetDeviceAddress());
668     if (!device.IsValid()) {
669         WIFI_LOGE("P2pStateMachine::IsConfigUnusable: failed to get device");
670         return P2pConfigErrCode::MAC_NOT_FOUND;
671     }
672     if (config.GetGroupOwnerIntent() < AUTO_GROUP_OWNER_VALUE ||
673         config.GetGroupOwnerIntent() > GROUP_OWNER_MAX_INTENT) {
674         WIFI_LOGE("P2pStateMachine::IsConfigUnusable: invalid groupOwnerIntent");
675         return P2pConfigErrCode::ERR_INTENT;
676     }
677     if (config.GetGroupName().length() > NETWORK_NAME_MAX_LENGTH) {
678         WIFI_LOGE("P2pStateMachine::IsConfigUnusable: invalid group name");
679         return P2pConfigErrCode::ERR_SIZE_NW_NAME;
680     }
681     return P2pConfigErrCode::SUCCESS;
682 }
683 
IsConfigUsableAsGroup(WifiP2pConfigInternal config)684 bool P2pStateMachine::IsConfigUsableAsGroup(WifiP2pConfigInternal config)
685 {
686     if (config.GetDeviceAddress().empty()) {
687         return false;
688     }
689     if (IsUsableGroupName(config.GetGroupName()) && !config.GetPassphrase().empty()) {
690         return true;
691     }
692     return false;
693 }
694 
CancelSupplicantSrvDiscReq()695 void P2pStateMachine::CancelSupplicantSrvDiscReq()
696 {
697     if (serviceManager.GetQueryId().empty()) {
698         return;
699     }
700 
701     WifiErrorNo retCode = WifiP2PHalInterface::GetInstance().CancelReqServiceDiscovery(serviceManager.GetQueryId());
702     if (retCode != WifiErrorNo::WIFI_HAL_OPT_OK) {
703         WIFI_LOGI("The request has been processed normally.");
704     } else {
705         serviceManager.SetQueryId(std::string(""));
706     }
707     return;
708 }
709 
NotifyUserInvitationSentMessage(const std::string & pin,const std::string & peerAddress) const710 void P2pStateMachine::NotifyUserInvitationSentMessage(const std::string &pin, const std::string &peerAddress) const
711 {
712     WIFI_LOGI("P2pStateMachine::NotifyUserInvitationSentMessage  enter");
713     std::function<void(AlertDialog &, std::any)> event = [](AlertDialog &dlg, std::any msg) {
714         AlertDialog dlgBuf = dlg;
715         std::any msgBuf = msg;
716         WIFI_LOGI("The user closes the display window.");
717     };
718     AlertDialog &dialog = AbstractUI::GetInstance().Build();
719     std::string message = "NotifyInvitationSent: " "Receiving Device Address:" + peerAddress + "PIN:" + pin;
720     dialog.SetTitle("Invitation Sent");
721     dialog.SetMessage(message);
722     dialog.SetButton("OK", event, nullptr);
723     AbstractUI::GetInstance().ShowAlerDialog(dialog);
724 }
725 
NotifyUserProvDiscShowPinRequestMessage(const std::string & pin,const std::string & peerAddress)726 void P2pStateMachine::NotifyUserProvDiscShowPinRequestMessage(const std::string &pin, const std::string &peerAddress)
727 {
728     WIFI_LOGI("P2pStateMachine::NotifyUserProvDiscShowPinRequestMessage  enter");
729     auto sendMessage =
730         std::bind(static_cast<void (StateMachine::*)(int)>(&StateMachine::SendMessage), this, std::placeholders::_1);
731     std::function<void(AlertDialog &, std::any)> acceptEvent = [=](AlertDialog &dlg, std::any msg) {
732         AlertDialog dlgBuf = dlg;
733         std::any msgBuf = msg;
734         sendMessage(static_cast<int>(P2P_STATE_MACHINE_CMD::INTERNAL_CONN_USER_CONFIRM));
735     };
736 
737     AlertDialog &dialog = AbstractUI::GetInstance().Build();
738     std::string message = "NotifyP2pProvDiscShowPinRequest: " "Receiving Device Address:" + peerAddress + "PIN:" + pin;
739     dialog.SetMessage(message);
740     dialog.SetTitle("Invitation Sent");
741     /* The third parameter supplements the state machine event. INTERNAL_CONN_USER_CONFIRM */
742     dialog.SetButton("accepts", acceptEvent, nullptr);
743     AbstractUI::GetInstance().ShowAlerDialog(dialog);
744 }
745 
NotifyUserInvitationReceivedMessage()746 void P2pStateMachine::NotifyUserInvitationReceivedMessage()
747 {
748     WIFI_LOGI("P2pStateMachine::NotifyUserInvitationReceivedMessage  enter");
749     const std::string inputBoxPin("input pin:");
750     auto sendMessage = std::bind(static_cast<void (StateMachine::*)(int, const std::any &)>(&StateMachine::SendMessage),
751         this,
752         std::placeholders::_1,
753         std::placeholders::_2);
754     const WpsInfo &wps = savedP2pConfig.GetWpsInfo();
755     std::function<void(AlertDialog &, std::any)> acceptEvent = [=](AlertDialog &dlg, std::any msg) {
756         std::any msgBuf = msg;
757         std::any anyPin;
758         if (wps.GetWpsMethod() == WpsMethod::WPS_METHOD_KEYPAD) {
759             anyPin = dlg.GetInputBox(inputBoxPin);
760         }
761         sendMessage(static_cast<int>(P2P_STATE_MACHINE_CMD::INTERNAL_CONN_USER_ACCEPT), anyPin);
762     };
763 
764     std::function<void(AlertDialog &, std::any)> rejectEvent = [=](AlertDialog &dlg, std::any msg) {
765         AlertDialog dlgBuf = dlg;
766         std::any andMsg = msg;
767         /* PEER_CONNECTION_USER_REJECT -> INTERNAL_CONN_USER_ACCEPT @2022-11-24 */
768         SendMessage(static_cast<int>(P2P_STATE_MACHINE_CMD::INTERNAL_CONN_USER_ACCEPT), andMsg);
769     };
770 
771     AlertDialog &dialog = AbstractUI::GetInstance().Build();
772     std::string message = "NotifyInvitationReceived: "
773         "Receiving device:" +
774         deviceManager.GetDeviceName(savedP2pConfig.GetDeviceAddress());
775     dialog.SetButton("accepts", acceptEvent, nullptr);
776     dialog.SetButton("rejects", rejectEvent, nullptr);
777 
778     switch (wps.GetWpsMethod()) {
779         case WpsMethod::WPS_METHOD_KEYPAD: {
780             dialog.SetInputBox(inputBoxPin);
781             break;
782         }
783         case WpsMethod::WPS_METHOD_DISPLAY: {
784             message += std::string("PIN:") + wps.GetPin();
785             break;
786         }
787         default:
788             break;
789     }
790     dialog.SetMessage(message);
791     AbstractUI::GetInstance().ShowAlerDialog(dialog);
792 }
793 
P2pConnectByShowingPin(const WifiP2pConfigInternal & config) const794 void P2pStateMachine::P2pConnectByShowingPin(const WifiP2pConfigInternal &config) const
795 {
796     if (config.GetDeviceAddress().empty()) {
797         WIFI_LOGE("Invalid address parameter.");
798         return;
799     }
800 
801     WifiP2pDevice device = FetchNewerDeviceInfo(config.GetDeviceAddress());
802     if (!device.IsValid()) {
803         WIFI_LOGE("Invalid device obtained.");
804         return;
805     }
806 
807     std::string pin;
808     if (WifiErrorNo::WIFI_HAL_OPT_OK !=
809         WifiP2PHalInterface::GetInstance().Connect(config, device.IsGroupOwner(), pin)) {
810         WIFI_LOGE("Connection failed.");
811     }
812 
813     if (!pin.empty()) {
814         WIFI_LOGI("connect return pin is %{private}s", pin.c_str());
815         NotifyUserInvitationSentMessage(pin, config.GetDeviceAddress());
816     }
817 }
818 
HandlerDiscoverPeers()819 void P2pStateMachine::HandlerDiscoverPeers()
820 {
821     WIFI_LOGD("p2p_enabled_state recv CMD_DEVICE_DISCOVERS");
822     CancelSupplicantSrvDiscReq();
823     WifiErrorNo retCode = WifiP2PHalInterface::GetInstance().P2pFind(DISC_TIMEOUT_S);
824     if (retCode == WifiErrorNo::WIFI_HAL_OPT_OK) {
825         WIFI_LOGD("call P2pFind successful, CMD_DEVICE_DISCOVERS successful.");
826         BroadcastActionResult(P2pActionCallback::DiscoverDevices, ErrCode::WIFI_OPT_SUCCESS);
827         BroadcastP2pDiscoveryChanged(true);
828     } else {
829         WIFI_LOGE("call P2pFind failed, ErrorCode: %{public}d", static_cast<int>(retCode));
830         BroadcastActionResult(P2pActionCallback::DiscoverDevices, ErrCode::WIFI_OPT_FAILED);
831     }
832 }
833 
ChangeConnectedStatus(P2pConnectedState connectedState)834 void P2pStateMachine::ChangeConnectedStatus(P2pConnectedState connectedState)
835 {
836     WIFI_LOGI("ChangeConnectedStatus, connectedState: %{public}d", connectedState);
837     WifiP2pLinkedInfo p2pInfo;
838     WifiConfigCenter::GetInstance().GetP2pInfo(p2pInfo);
839     P2pConnectedState curP2pConnectedState = p2pInfo.GetConnectState();
840     if (curP2pConnectedState == connectedState) {
841         WIFI_LOGD("The connection status is the same, ignore this status!");
842         return;
843     }
844 
845     p2pInfo.SetConnectState(connectedState);
846     WifiConfigCenter::GetInstance().SaveP2pInfo(p2pInfo);
847     groupManager.SaveP2pInfo(p2pInfo);
848 
849     if (connectedState == P2pConnectedState::P2P_CONNECTED) {
850         std::string deviceAddress;
851         savedP2pConfig.SetDeviceAddress(deviceAddress);
852         UpdateOwnDevice(P2pDeviceStatus::PDS_CONNECTED);
853         if (GetIsNeedDhcp() != DHCPTYPE::DHCP_LEGACEGO) {
854             BroadcastP2pConnectionChanged();
855         }
856     }
857 
858     if (connectedState == P2pConnectedState::P2P_DISCONNECTED) {
859         UpdateOwnDevice(P2pDeviceStatus::PDS_AVAILABLE);
860         ClearWifiP2pInfo();
861         BroadcastP2pConnectionChanged();
862         deviceManager.UpdateAllDeviceStatus(P2pDeviceStatus::PDS_AVAILABLE);
863     }
864     return;
865 }
866 
ClearWifiP2pInfo()867 void P2pStateMachine::ClearWifiP2pInfo()
868 {
869     WifiP2pLinkedInfo p2pInfo;
870     WifiConfigCenter::GetInstance().SaveP2pInfo(p2pInfo);
871     groupManager.SaveP2pInfo(p2pInfo);
872 }
873 
StartDhcpServer()874 bool P2pStateMachine::StartDhcpServer()
875 {
876     Ipv4Address ipv4(Ipv4Address::defaultInetAddress);
877     Ipv6Address ipv6(Ipv6Address::INVALID_INET6_ADDRESS);
878     pDhcpResultNotify->SetP2pStateMachine(this, &groupManager);
879     serverCallBack.OnServerSuccess = P2pStateMachine::DhcpResultNotify::OnDhcpServerSuccess;
880     m_DhcpdInterface.RegisterDhcpCallBack(groupManager.GetCurrentGroup().GetInterface(), serverCallBack);
881     const std::string ipAddress = DEFAULT_P2P_IPADDR;
882     if (!m_DhcpdInterface.StartDhcpServerFromInterface(groupManager.GetCurrentGroup().GetInterface(),
883                                                        ipv4, ipv6, ipAddress, true)) {
884         return false;
885     }
886     SetWifiP2pInfoWhenGroupFormed(ipv4.GetAddressWithString());
887     WifiP2pGroupInfo currGroup = groupManager.GetCurrentGroup();
888     currGroup.SetGoIpAddress(ipv4.GetAddressWithString());
889     groupManager.SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, currGroup);
890 
891     WIFI_LOGI("Start add route");
892     WifiNetAgent::GetInstance().AddRoute(groupManager.GetCurrentGroup().GetInterface(),
893         ipv4.GetAddressWithString(), ipv4.GetAddressPrefixLength());
894     WIFI_LOGI("Start dhcp server for P2p finished.");
895     WriteWifiP2pStateHiSysEvent(groupManager.GetCurrentGroup().GetInterface(), P2P_GO, P2P_ON);
896     return true;
897 }
898 
StopDhcpServer()899 bool P2pStateMachine::StopDhcpServer()
900 {
901     if (!groupManager.GetCurrentGroup().GetInterface().empty()) {
902         WriteWifiP2pStateHiSysEvent(groupManager.GetCurrentGroup().GetInterface(), P2P_GO, P2P_OFF);
903     }
904     return m_DhcpdInterface.StopDhcp(groupManager.GetCurrentGroup().GetInterface());
905 }
906 
907 P2pStateMachine* P2pStateMachine::DhcpResultNotify::pP2pStateMachine = nullptr;
908 WifiP2pGroupManager* P2pStateMachine::DhcpResultNotify::groupManager = nullptr;
DhcpResultNotify()909 P2pStateMachine::DhcpResultNotify::DhcpResultNotify()
910 {}
911 
~DhcpResultNotify()912 P2pStateMachine::DhcpResultNotify::~DhcpResultNotify()
913 {}
914 
SetP2pStateMachine(P2pStateMachine * p2pStateMachine,WifiP2pGroupManager * pGroupManager)915 void P2pStateMachine::DhcpResultNotify::SetP2pStateMachine(P2pStateMachine *p2pStateMachine,
916     WifiP2pGroupManager *pGroupManager)
917 {
918     pP2pStateMachine = p2pStateMachine;
919     groupManager = pGroupManager;
920 }
921 
OnSuccess(int status,const char * ifname,DhcpResult * result)922 void P2pStateMachine::DhcpResultNotify::OnSuccess(int status, const char *ifname, DhcpResult *result)
923 {
924     if (ifname == nullptr || result == nullptr) {
925         WIFI_LOGE("P2P DhcpResultNotify OnSuccess, ifname or result is nullptr, status: %{public}d, ifname: %{public}s",
926             status, ifname);
927         return;
928     }
929     WIFI_LOGI("Enter P2P DhcpResultNotify::OnSuccess, status: %{public}d, ifname: %{public}s", status, ifname);
930     WifiP2pLinkedInfo p2pInfo;
931     WifiConfigCenter::GetInstance().GetP2pInfo(p2pInfo);
932     WIFI_LOGI("Set GO IP: %{private}s", result->strOptServerId);
933     p2pInfo.SetIsGroupOwnerAddress(result->strOptServerId);
934     WifiP2pGroupInfo currGroup = groupManager->GetCurrentGroup();
935     currGroup.SetGoIpAddress(result->strOptServerId);
936     currGroup.SetGcIpAddress(result->strOptClientId);
937     groupManager->SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, currGroup);
938     WifiConfigCenter::GetInstance().SaveP2pInfo(p2pInfo);
939     groupManager->SaveP2pInfo(p2pInfo);
940     pP2pStateMachine->BroadcastP2pConnectionChanged();
941     WIFI_LOGI("Start add route on dhcp success");
942     WifiNetAgent::GetInstance().AddRoute(ifname, result->strOptClientId, IpTools::GetMaskLength(result->strOptSubnet));
943     WIFI_LOGI("DhcpResultNotify::OnSuccess end");
944     std::string serverIp = result->strOptServerId;
945     std::string clientIp = result->strOptClientId;
946     /* trigger arp for miracast */
947     pP2pStateMachine->DoP2pArp(serverIp, clientIp);
948 }
949 
OnFailed(int status,const char * ifname,const char * reason)950 void P2pStateMachine::DhcpResultNotify::OnFailed(int status, const char *ifname, const char *reason)
951 {
952     WIFI_LOGI("Enter DhcpResultNotify::OnFailed, status: %{public}d, reason: %{public}s. RemoveGroup: %{private}s",
953         status,
954         reason,
955         ifname);
956     std::string ifaceifname = ifname;
957     if (pP2pStateMachine->p2pDevIface == ifaceifname) {
958         pP2pStateMachine->p2pDevIface = "";
959     }
960     WifiP2PHalInterface::GetInstance().GroupRemove(ifaceifname);
961 }
962 
OnDhcpServerSuccess(const char * ifname,DhcpStationInfo * stationInfos,size_t size)963 void P2pStateMachine::DhcpResultNotify::OnDhcpServerSuccess(const char *ifname,
964     DhcpStationInfo *stationInfos, size_t size)
965 {
966     WIFI_LOGI("Dhcp notify ServerSuccess. ifname:%s", ifname);
967     std::vector<GcInfo> gcInfos;
968     for (size_t i = 0; i < size; i++) {
969         GcInfo gcInfo;
970         gcInfo.mac = stationInfos[i].macAddr;
971         gcInfo.ip = stationInfos[i].ipAddr;
972         gcInfo.host = stationInfos[i].deviceName;
973         gcInfos.emplace_back(gcInfo);
974     }
975     if (ErrCode::WIFI_OPT_SUCCESS != pP2pStateMachine->AddClientInfo(gcInfos)) {
976         WIFI_LOGE("AddClientInfo failed");
977     }
978 }
979 
StartDhcpClientInterface()980 void P2pStateMachine::StartDhcpClientInterface()
981 {
982     WriteWifiP2pStateHiSysEvent(groupManager.GetCurrentGroup().GetInterface(), P2P_GC, P2P_ON);
983     if (GetIsNeedDhcp() == DHCPTYPE::NO_DHCP) {
984         WIFI_LOGI("The service of this time does not need DHCP.");
985         return;
986     }
987 
988     clientCallBack.OnIpSuccessChanged = DhcpResultNotify::OnSuccess;
989     clientCallBack.OnIpFailChanged = DhcpResultNotify::OnFailed;
990     pDhcpResultNotify->SetP2pStateMachine(this, &groupManager);
991     int result = RegisterDhcpClientCallBack(groupManager.GetCurrentGroup().GetInterface().c_str(), &clientCallBack);
992     if (result != 0) {
993         WIFI_LOGE("RegisterDhcpClientCallBack failed!");
994         return;
995     }
996     result = StartDhcpClient(groupManager.GetCurrentGroup().GetInterface().c_str(), false);
997     if (result != 0) {
998         WIFI_LOGE("StartDhcpClient failed!");
999         return;
1000     }
1001     WIFI_LOGI("StartDhcpClient ok");
1002 }
1003 
HandleP2pServiceResp(const WifiP2pServiceResponse & resp,const WifiP2pDevice & dev) const1004 void P2pStateMachine::HandleP2pServiceResp(const WifiP2pServiceResponse &resp, const WifiP2pDevice &dev) const
1005 {
1006     WIFI_LOGI("HandleP2pServiceResp");
1007     serviceManager.AddDeviceService(resp, dev);
1008     if (resp.GetServiceStatus() == P2pServiceStatus::PSRS_SERVICE_PROTOCOL_NOT_AVAILABLE) {
1009         WIFI_LOGD("Service protocol is not available.");
1010         return;
1011     }
1012     if (resp.GetProtocolType() == P2pServicerProtocolType::SERVICE_TYPE_BONJOUR) {
1013         WifiP2pDnsSdServiceResponse dnsSrvResp = WifiP2pDnsSdServiceResponse(resp);
1014         if (!dnsSrvResp.ParseData()) {
1015             WIFI_LOGE("Parse WifiP2pDnsServiceResponse failed!");
1016             return;
1017         }
1018         serviceManager.UpdateServiceName(dev.GetDeviceAddress(), dynamic_cast<WifiP2pServiceResponse &>(dnsSrvResp));
1019         if (dnsSrvResp.GetDnsType() == WifiP2pDnsSdServiceInfo::DNS_PTR_TYPE) {
1020             BroadcastDnsSdServiceResult(dnsSrvResp.GetInstanceName(), dnsSrvResp.GetQueryName(), dev);
1021             return;
1022         }
1023         if (dnsSrvResp.GetDnsType() == WifiP2pDnsSdServiceInfo::DNS_TXT_TYPE) {
1024             BroadcastDnsSdTxtRecordResult(dnsSrvResp.GetQueryName(), dnsSrvResp.GetTxtRecord(), dev);
1025             return;
1026         }
1027         WIFI_LOGE("Parse WifiP2pDnsSdServiceResponse Dnstype failed!");
1028         return;
1029     }
1030     if (resp.GetProtocolType() == P2pServicerProtocolType::SERVICE_TYPE_UP_NP) {
1031         WifiP2pUpnpServiceResponse upnpSrvResp =
1032             WifiP2pUpnpServiceResponse::Create(resp.GetServiceStatus(), resp.GetTransactionId(), resp.GetData());
1033         if (upnpSrvResp.ParseData()) {
1034             serviceManager.UpdateServiceName(
1035                 dev.GetDeviceAddress(), dynamic_cast<WifiP2pServiceResponse &>(upnpSrvResp));
1036             BroadcastUpnpServiceResult(upnpSrvResp.GetUniqueServNames(), dev);
1037         } else {
1038             WIFI_LOGE("Parse WifiP2pUpnpServiceResponse failed!");
1039         }
1040         return;
1041     }
1042 
1043     BroadcastServiceResult(resp.GetProtocolType(), resp.GetData(), dev);
1044     return;
1045 }
1046 
GetAvailableFreqByBand(GroupOwnerBand band) const1047 int P2pStateMachine::GetAvailableFreqByBand(GroupOwnerBand band) const
1048 {
1049     std::vector<int> freqList;
1050     if (band != GroupOwnerBand::GO_BAND_2GHZ && band != GroupOwnerBand::GO_BAND_5GHZ) {
1051         WIFI_LOGE("Not 2.4GHz or 5GHz band!");
1052         return 0;
1053     }
1054     if (WifiP2PHalInterface::GetInstance().P2pGetSupportFrequenciesByBand(static_cast<int>(band), freqList) ==
1055         WifiErrorNo::WIFI_HAL_OPT_FAILED) {
1056         constexpr int DEFAULT_5G_FREQUENCY = 5745; // channal:149, frequency:5745
1057         if (band == GroupOwnerBand::GO_BAND_5GHZ) {
1058             WIFI_LOGE("Get support frequencies failed, use default 5g frequency!");
1059             return DEFAULT_5G_FREQUENCY;
1060         }
1061         constexpr int DEFAULT_2G_FREQUENCY = 2412;
1062         if (band == GroupOwnerBand::GO_BAND_2GHZ) {
1063             WIFI_LOGE("Get support frequencies failed, use default 2g frequency!");
1064             return DEFAULT_2G_FREQUENCY;
1065         }
1066         WIFI_LOGE("Cannot get support frequencies according to band, choose random frequency");
1067         return 0;
1068     }
1069     std::random_device rd;
1070     int randomIndex = static_cast<int>(static_cast<size_t>(std::abs(static_cast<int>(rd()))) % freqList.size());
1071     int retFreq = freqList.at(randomIndex);
1072     return retFreq;
1073 }
1074 
SetGroupConfig(const WifiP2pConfigInternal & config,bool newGroup) const1075 bool P2pStateMachine::SetGroupConfig(const WifiP2pConfigInternal &config, bool newGroup) const
1076 {
1077     WifiErrorNo ret;
1078     HalP2pGroupConfig wpaConfig;
1079     WifiP2pGroupInfo group;
1080     if (newGroup) {
1081         WIFI_LOGI("SetGroupConfig, new group");
1082         wpaConfig.ssid = config.GetGroupName();
1083         wpaConfig.psk = config.GetPassphrase();
1084         wpaConfig.bssid = deviceManager.GetThisDevice().GetDeviceAddress();
1085         const int p2pDisabled = 2;
1086         wpaConfig.disabled = p2pDisabled;
1087         const int p2pMode = 3;
1088         wpaConfig.mode = p2pMode;
1089     } else {
1090         WIFI_LOGI("SetGroupConfig, not new group");
1091         HalP2pGroupConfig knownConfig;
1092         ret = WifiP2PHalInterface::GetInstance().P2pGetGroupConfig(config.GetNetId(), knownConfig);
1093         if (ret == WifiErrorNo::WIFI_HAL_OPT_FAILED) {
1094             WIFI_LOGW("P2pGetGroupConfig failed");
1095         }
1096         if (!config.GetGroupName().empty()) {
1097             wpaConfig.ssid = config.GetGroupName();
1098         } else {
1099             wpaConfig.ssid = knownConfig.ssid;
1100         }
1101         if (!config.GetPassphrase().empty()) {
1102             wpaConfig.psk = config.GetPassphrase();
1103         } else {
1104             WIFI_LOGI("Passphrase empty!");
1105             wpaConfig.psk = std::string("");
1106         }
1107         wpaConfig.authAlg = knownConfig.authAlg;
1108         wpaConfig.bssid = knownConfig.bssid;
1109         wpaConfig.keyMgmt = knownConfig.keyMgmt;
1110         wpaConfig.pairwise = knownConfig.pairwise;
1111         wpaConfig.proto = knownConfig.proto;
1112         wpaConfig.disabled = knownConfig.disabled;
1113         wpaConfig.mode = knownConfig.mode;
1114     }
1115     group.SetGroupName(config.GetGroupName());
1116     group.SetPassphrase(config.GetPassphrase());
1117     group.SetNetworkId(config.GetNetId());
1118     groupManager.AddOrUpdateGroup(group);
1119     ret = WifiP2PHalInterface::GetInstance().P2pSetGroupConfig(config.GetNetId(), wpaConfig);
1120     if (ret == WifiErrorNo::WIFI_HAL_OPT_FAILED) {
1121         return false;
1122     } else {
1123         return true;
1124     }
1125 }
1126 
DealCreateNewGroupWithConfig(const WifiP2pConfigInternal & config,int freq) const1127 bool P2pStateMachine::DealCreateNewGroupWithConfig(const WifiP2pConfigInternal &config, int freq) const
1128 {
1129     WifiP2pConfigInternal cfgBuf = config;
1130     int createdNetId = -1;
1131     int netId = cfgBuf.GetNetId();
1132 
1133     std::vector<WifiP2pGroupInfo> groupInfo = groupManager.GetGroups();
1134     for (auto iter = groupInfo.begin(); iter != groupInfo.end(); ++iter) {
1135         if (iter->GetGroupName() == config.GetGroupName()) {
1136             WIFI_LOGE("Cannot use a exist group name!");
1137             return false;
1138         }
1139     }
1140 
1141     WifiErrorNo ret = WifiP2PHalInterface::GetInstance().P2pAddNetwork(createdNetId);
1142     if (ret == WIFI_HAL_OPT_OK) {
1143         cfgBuf.SetNetId(createdNetId);
1144         if (!SetGroupConfig(cfgBuf, true)) {
1145             WIFI_LOGW("Some configuration settings failed!");
1146         }
1147         ret = WifiP2PHalInterface::GetInstance().GroupAdd(true, createdNetId, freq);
1148     }
1149 
1150     if (ret == WIFI_HAL_OPT_FAILED || netId == TEMPORARY_NET_ID) {
1151         WIFI_LOGD("Remove network %{public}d!", createdNetId);
1152         WifiP2PHalInterface::GetInstance().RemoveNetwork(createdNetId);
1153         WifiP2pGroupInfo removedInfo;
1154         removedInfo.SetNetworkId(createdNetId);
1155         groupManager.RemoveGroup(removedInfo);
1156     }
1157 
1158     UpdateGroupManager();
1159     UpdatePersistentGroups();
1160     return (ret == WIFI_HAL_OPT_FAILED) ? false : true;
1161 }
1162 
HasPersisentGroup(void)1163 bool P2pStateMachine::HasPersisentGroup(void)
1164 {
1165     std::vector<WifiP2pGroupInfo> grpInfo = groupManager.GetGroups();
1166     return !grpInfo.empty();
1167 }
1168 
UpdateGroupInfoToWpa() const1169 void P2pStateMachine::UpdateGroupInfoToWpa() const
1170 {
1171     WIFI_LOGI("Start update group info to wpa");
1172     std::vector<WifiP2pGroupInfo> grpInfo = groupManager.GetGroups();
1173     if (grpInfo.size() > 0) {
1174         if (WifiP2PHalInterface::GetInstance().RemoveNetwork(-1) != WIFI_HAL_OPT_OK) {
1175             WIFI_LOGE("Failed to delete all group info before update group info to wpa! Stop update!");
1176             return;
1177         }
1178     }
1179 
1180     int createdNetId = -1;
1181     WifiP2pGroupInfo grpBuf;
1182     HalP2pGroupConfig wpaConfig;
1183     for (unsigned int i = 0; i < grpInfo.size(); ++i) {
1184         grpBuf = grpInfo.at(i);
1185         WifiErrorNo ret = WifiP2PHalInterface::GetInstance().P2pAddNetwork(createdNetId);
1186         if (ret == WIFI_HAL_OPT_OK) {
1187             grpBuf.SetNetworkId(createdNetId);
1188             wpaConfig.ssid = grpBuf.GetGroupName();
1189             wpaConfig.psk = grpBuf.GetPassphrase();
1190             wpaConfig.bssid = grpBuf.GetOwner().GetDeviceAddress();
1191             const int p2pDisabled = 2;
1192             wpaConfig.disabled = p2pDisabled;
1193             if (grpBuf.GetOwner().GetDeviceAddress() == deviceManager.GetThisDevice().GetDeviceAddress()) {
1194                 const int p2pMode = 3;
1195                 wpaConfig.mode = p2pMode;
1196             } else {
1197                 wpaConfig.mode = 0;
1198             }
1199             WifiP2PHalInterface::GetInstance().P2pSetGroupConfig(createdNetId, wpaConfig);
1200             grpInfo.at(i) = grpBuf;
1201         } else {
1202             WIFI_LOGW("AddNetwork failed when add %{public}s group!", grpBuf.GetGroupName().c_str());
1203         }
1204     }
1205     return;
1206 }
1207 
RemoveGroupByDevice(WifiP2pDevice & device) const1208 void P2pStateMachine::RemoveGroupByDevice(WifiP2pDevice &device) const
1209 {
1210     int networkId = groupManager.GetGroupNetworkId(device);
1211     if (networkId != -1) {
1212         RemoveGroupByNetworkId(networkId);
1213     }
1214     return;
1215 }
1216 
1217 
GetIsNeedDhcp() const1218 DHCPTYPE P2pStateMachine::GetIsNeedDhcp() const
1219 {
1220     WIFI_LOGI("Get need dhcp flag %{public}d", (int)m_isNeedDhcp);
1221     return m_isNeedDhcp;
1222 }
1223 
SetIsNeedDhcp(DHCPTYPE dhcpType)1224 void P2pStateMachine::SetIsNeedDhcp(DHCPTYPE dhcpType)
1225 {
1226     WIFI_LOGI("Set need dhcp flag %{public}d", dhcpType);
1227     m_isNeedDhcp = dhcpType;
1228 }
1229 
ClearGroup() const1230 void P2pStateMachine::ClearGroup() const
1231 {
1232     struct ifaddrs *ifaddr = nullptr;
1233     struct ifaddrs *ifa = nullptr;
1234     int n;
1235     std::string iface;
1236 
1237     if (getifaddrs(&ifaddr) == -1) {
1238         WIFI_LOGE("getifaddrs failed, error is %{public}d", errno);
1239         return;
1240     }
1241     for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++) {
1242         if (strncmp("p2p-", ifa->ifa_name, P2P_PREFIX_LEN) == 0) {
1243             WIFI_LOGE("has p2p group, remove");
1244             iface.assign(ifa->ifa_name);
1245             WifiP2PHalInterface::GetInstance().GroupRemove(iface);
1246             // current p2p group can be created only one,
1247             // if there are multiple groups can be created in the future, the break need to be modified.
1248             break;
1249         }
1250     }
1251     freeifaddrs(ifaddr);
1252 }
1253 
HandlerDisableRandomMac(int setmode) const1254 bool P2pStateMachine::HandlerDisableRandomMac(int setmode) const
1255 {
1256     WifiP2PHalInterface::GetInstance().SetRandomMacAddr(setmode);
1257     WifiP2PHalInterface::GetInstance().DeliverP2pData(CMD_TYPE_SET, DATA_TYPE_P2P_BUSINESS, CARRY_DATA_MIRACAST);
1258     return EXECUTED;
1259 }
1260 
StopP2pDhcpClient()1261 void P2pStateMachine::StopP2pDhcpClient()
1262 {
1263     WIFI_LOGI("%{public}s enter", __func__);
1264     std::string ifName = groupManager.GetCurrentGroup().GetInterface();
1265     if (ifName.empty()) {
1266         ifName = "p2p";
1267         WIFI_LOGE("%{public}s ifName is empty", __func__);
1268     }
1269     StopDhcpClient(ifName.c_str(), false);
1270 }
1271 
DoP2pArp(std::string serverIp,std::string clientIp)1272 void P2pStateMachine::DoP2pArp(std::string serverIp, std::string clientIp)
1273 {
1274     ArpChecker arpChecker;
1275     unsigned char macAddr[MAC_LEN];
1276     std::string ifName = groupManager.GetCurrentGroup().GetInterface();
1277     if (!MacAddress::GetMacAddr(ifName, macAddr)) {
1278         WIFI_LOGE("get interface mac failed");
1279         return;
1280     }
1281     std::string macAddress = MacArrayToStr(macAddr);
1282     arpChecker.Start(ifName, macAddress, clientIp, serverIp);
1283     arpChecker.DoArpCheck(ARP_TIMEOUT, true);
1284 }
1285 
SetEnhanceService(IEnhanceService * enhanceService)1286 void P2pStateMachine::SetEnhanceService(IEnhanceService* enhanceService)
1287 {
1288     p2pGroupOperatingState.SetEnhanceService(enhanceService);
1289 }
1290 } // namespace Wifi
1291 } // namespace OHOS
1292