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 ®Type, 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