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 #ifndef OHOS_P2P_STATE_MACHINE_H
16 #define OHOS_P2P_STATE_MACHINE_H
17 
18 #include <mutex>
19 #include "state_machine.h"
20 #include "ip2p_service_callbacks.h"
21 #include "p2p_define.h"
22 #include "p2p_monitor.h"
23 #include "wifi_p2p_service_manager.h"
24 #include "dhcpd_interface.h"
25 #include "authorizing_negotiation_request_state.h"
26 #include "group_formed_state.h"
27 #include "group_negotiation_state.h"
28 #include "invitation_received_state.h"
29 #include "invitation_request_state.h"
30 #include "p2p_default_state.h"
31 #include "p2p_disabled_state.h"
32 #include "p2p_disabling_state.h"
33 #include "p2p_enabled_state.h"
34 #include "p2p_enabling_state.h"
35 #include "p2p_group_formation_state.h"
36 #include "p2p_group_join_state.h"
37 #include "p2p_group_operating_state.h"
38 #include "p2p_idle_state.h"
39 #include "p2p_inviting_state.h"
40 #include "provision_discovery_state.h"
41 #include "abstract_ui.h"
42 #include "wifi_hid2d_service_utils.h"
43 #include "dhcp_c_api.h"
44 #include "p2p_group_remove_state.h"
45 
46 namespace OHOS {
47 namespace Wifi {
48 const int MIN_GROUP_NAME_LENGTH = 9;
49 const int MAX_GROUP_NAME_LENGTH = 32;
50 const int DISC_TIMEOUT_S = 120;
51 enum {
52     P2P_GC,
53     P2P_GO,
54 };
55 enum {
56     P2P_OFF,
57     P2P_ON,
58 };
59 class P2pStateMachine : public StateMachine {
60     class DhcpResultNotify {
61     public:
62         explicit DhcpResultNotify();
63         ~DhcpResultNotify();
64         static void OnSuccess(int status, const char *ifname, DhcpResult *result);
65         static void OnFailed(int status, const char *ifname, const char *reason);
66         static void SetP2pStateMachine(P2pStateMachine *p2pStateMachine, WifiP2pGroupManager *pGroupManager);
67         static void OnDhcpServerSuccess(const char *ifname, DhcpStationInfo *stationInfos, size_t size);
68     private:
69        static P2pStateMachine *pP2pStateMachine;
70        static WifiP2pGroupManager *groupManager;
71     };
72 
73     friend class AuthorizingNegotiationRequestState;
74     friend class GroupFormedState;
75     friend class GroupNegotiationState;
76     friend class InvitationReceivedState;
77     friend class InvitationRequestState;
78     friend class P2pDefaultState;
79     friend class P2pDisabledState;
80     friend class P2pDisablingState;
81     friend class P2pEnabledState;
82     friend class P2pEnablingState;
83     friend class P2pGroupFormationState;
84     friend class P2pGroupJoinState;
85     friend class P2pGroupOperatingState;
86     friend class P2pIdleState;
87     friend class P2pInvitingState;
88     friend class ProvisionDiscoveryState;
89     friend class P2pGroupRemoveState;
90     FRIEND_GTEST(P2pStateMachine);
91 
92 public:
93     /**
94      * @Description Construct a new P2pStateMachine object.
95      */
96     P2pStateMachine(P2pMonitor &, WifiP2pGroupManager &, WifiP2pDeviceManager &, WifiP2pServiceManager &,
97         AuthorizingNegotiationRequestState &, GroupFormedState &, GroupNegotiationState &, InvitationReceivedState &,
98         InvitationRequestState &, P2pDefaultState &, P2pDisabledState &, P2pDisablingState &, P2pEnabledState &,
99         P2pEnablingState &, P2pGroupFormationState &, P2pGroupJoinState &, P2pGroupOperatingState &, P2pIdleState &,
100         P2pInvitingState &, ProvisionDiscoveryState &, P2pGroupRemoveState &);
101     /**
102      * @Description Destroy the P2pStateMachine object.
103      */
104     ~P2pStateMachine();
105     /**
106      * @Description - Initialize the state machine.
107      */
108     virtual void Initialize();
109 public:
110     /**
111      * @Description - Callbacks of event registered by the p2pService.
112      * @param  callback - event callback object
113      */
114     virtual void RegisterP2pServiceCallbacks(const IP2pServiceCallbacks &callback);
115 
116     /**
117      * @Description - Callbacks of event registered by the p2pService.
118      * @param  callback - event callback object
119      */
120     virtual void UnRegisterP2pServiceCallbacks(const IP2pServiceCallbacks &callback);
121 
122     /**
123      * @Description - Callbacks of event unregistered by the p2pService.
124      */
125     virtual void ClearAllP2pServiceCallbacks();
126 
127     /**
128      * @Description - Set is need dhcp.
129      * @param  isNeedDhcp - true: need, false: not need
130      */
131     void SetIsNeedDhcp(DHCPTYPE dhcpType);
132 
133     void SetEnhanceService(IEnhanceService* enhanceService);
134 private:
135     /**
136      * @Description Handle event of CMD_DEVICE_DISCOVERS
137      .
138      *
139      */
140     virtual void HandlerDiscoverPeers();
141 
142 private:
143     /**
144      * @Description - Register handler with the monitor.
145      */
146     virtual void RegisterEventHandler();
147 
148     /**
149      * @Description - Update device status and broadcast device status change events.
150      * @param  status - new device status
151      */
152     virtual void UpdateOwnDevice(P2pDeviceStatus status);
153     /**
154      * @Description - Update groupManager from wpa_supplicant.
155      */
156     virtual void UpdateGroupManager() const;
157     /**
158      * @Description - Update persistent groups and broadcast persistent groups status update event.
159      */
160     virtual void UpdatePersistentGroups() const;
161 
162     /**
163      * @Description - Determines whether the group is a persistent group.
164                       If the group is a persistent group, the system attempts to reinvoke the group.
165      * @param  config - determine the configurations related to the persistent group
166      * @return - bool  true:It is a persistent group and the reinvoke succeeds.
167                        false:Not a persistent group or reinvoke failure.
168      */
169     virtual bool ReawakenPersistentGroup(WifiP2pConfigInternal &config) const;
170 
171     /**
172      * @Description - Updates the latest device information based on the device address and returns.
173      * @param  deviceAddr - the device address
174      * @return - WifiP2pDevice
175      */
176     virtual WifiP2pDevice FetchNewerDeviceInfo(const std::string &deviceAddr) const;
177     /**
178      * @Description - Handle group creation failures.
179      */
180     virtual void DealGroupCreationFailed();
181 
182     /**
183      * @Description - Remove a group based on the network ID.
184      * @param  networkId - specifies the network ID of a group
185      */
186     virtual void RemoveGroupByNetworkId(int networkId) const;
187     /**
188      * @Description Updating the WifiP2pLinkedInfo information when a group is formed.
189      * @param  groupOwnerAddress - address of the group owner
190      */
191     virtual void SetWifiP2pInfoWhenGroupFormed(const std::string &groupOwnerAddress);
192 
193     /**
194      * @Description - Initialize own device information.
195      */
196     virtual void InitializeThisDevice();
197     /**
198      * @Description Check whether the specified network name is available.
199      *
200      * @param nwName - specified network name
201      * @return true - available
202      * @return false - not available
203      */
204     virtual bool IsUsableGroupName(std::string nwName);
205     /**
206      * @Description Check whether the specified P2P configuration is unavailable.
207      *
208      * @param config - specified P2P configuration
209      * @return P2pConfigErrCode - error code of WifiP2pConfig
210      */
211     virtual P2pConfigErrCode IsConfigUnusable(const WifiP2pConfigInternal &config);
212     /**
213      * @Description If the P2P is configured with a network name and passphrase, the configuration is valid as a group.
214      *
215      * @param config - P2P config
216      * @return true - valid
217      * @return false - invalid
218      */
219     virtual bool IsConfigUsableAsGroup(WifiP2pConfigInternal config);
220     /**
221      * @Description Purging service discovery requests in WPAS.
222      *
223      */
224     virtual void CancelSupplicantSrvDiscReq();
225     /**
226      * @Description Change the current P2P connection status.
227      *
228      * @param connectedState status of the connection
229      */
230     virtual void ChangeConnectedStatus(P2pConnectedState connectedState);
231     /**
232      * @Description Clear P2P connection information.
233      *
234      */
235     virtual void ClearWifiP2pInfo();
236     /**
237      * @Description Start dhcp client.
238      *
239      */
240     virtual void StartDhcpClientInterface();
241     /**
242      * @Description Processing the p2p service response result.
243      *
244      * @param resp - result of service response
245      * @param dev - source device
246      */
247     virtual void HandleP2pServiceResp(const WifiP2pServiceResponse &resp, const WifiP2pDevice &dev) const;
248     /**
249      * @Description Get the list of frequencies by band.
250      *
251      * @param band - specified band
252      * @return int - a random available frequency
253      */
254     virtual int GetAvailableFreqByBand(GroupOwnerBand band) const;
255     /**
256      * @Description Setting the group's configuration to WPA.
257      *
258      * @param config - p2p group's configuration
259      * @param newGroup - indicates whether the group is a new group
260      * @return true - all settings succeeded
261      * @return false - one of settings failed
262      */
263     virtual bool SetGroupConfig(const WifiP2pConfigInternal &config, bool newGroup) const;
264     /**
265      * @Description Processing function of using configuration to create a group.
266      *
267      * @param config - p2p group's configuration
268      * @param freq - the frequency when starting a group
269      * @return true - created successfully
270      * @return false - creation failed
271      */
272     virtual bool DealCreateNewGroupWithConfig(const WifiP2pConfigInternal &config, int freq) const;
273     /**
274      * @Description Update persistent group's info to wpa.
275      *
276      */
277     virtual void UpdateGroupInfoToWpa() const;
278 
279     /**
280      * @Description RemoveGroupByDevice
281      *
282      */
283     void RemoveGroupByDevice(WifiP2pDevice &device) const;
284 
285     /**
286      * @Description Get is need dhcp.
287      *
288      */
289     DHCPTYPE GetIsNeedDhcp() const;
290 
291     void ClearGroup() const;
292 
293     bool HasPersisentGroup(void);
294 
295     bool CheckIsDisplayDevice(const std::string &mac) const;
296 private:
297     /**
298      * @Description - Broadcast state change event.
299      * @param  state - current state
300      */
301     virtual void BroadcastP2pStatusChanged(P2pState state) const;
302     /**
303      * @Description - Peers update detected by broadcast.
304      */
305     virtual void BroadcastP2pPeersChanged() const;
306     /**
307      * @Description - Peers private update detected by broadcast.
308      */
309     virtual void BroadcastP2pPrivatePeersChanged(std::string &privateInfo) const;
310     /**
311      * @Description - Broadcast the scanned service information update.
312      */
313     virtual void BroadcastP2pServicesChanged() const;
314     /**
315      * @Description - Broadcast connection event changes.
316      */
317     virtual void BroadcastP2pConnectionChanged() const;
318     /**
319      * @Description - Broadcast own device change event.
320      * @param  device - own device information
321      */
322     virtual void BroadcastThisDeviceChanaged(const WifiP2pDevice &device) const;
323     /**
324      * @Description - Broadcast Discovery status.
325      * @param  isActive - current status
326      */
327     virtual void BroadcastP2pDiscoveryChanged(bool isActive) const;
328      /**
329      * @Description - Broadcast P2pGcJoinGroup event.
330      */
331     virtual void BroadcastP2pGcJoinGroup(GcInfo &info) const;
332 
333      /**
334      * @Description - Broadcast P2pGcLeaveGroup event.
335      */
336     virtual void BroadcastP2pGcLeaveGroup(WifiP2pDevice &device) const;
337     /**
338      * @Description - Broadcast persistent group update event.
339      */
340     virtual void BroadcastPersistentGroupsChanged() const;
341     /**
342      * @Description - For asynchronous operations, the operation result needs to be responded asynchronously.
343      * @param  action - corresponding action
344      * @param  result - action confirmation result
345      */
346     virtual void BroadcastActionResult(P2pActionCallback action, ErrCode result) const;
347     /**
348      * @Description Broadcast receive p2p service response result in addition to bonjour and upnp.
349      *
350      * @param serviceType - protocol type
351      * @param respData - service response data
352      * @param srcDevice - source device
353      */
354     virtual void BroadcastServiceResult(P2pServicerProtocolType serviceType,
355         const std::vector<unsigned char> &respData, const WifiP2pDevice &srcDevice) const;
356     /**
357      * @Description Broadcast receive bonjour service response result.
358      *
359      * @param instName - instance name
360      * @param regType - registration type
361      * @param srcDevice - source device
362      */
363     virtual void BroadcastDnsSdServiceResult(
364         const std::string &instName, const std::string &regType, const WifiP2pDevice &srcDevice) const;
365     /**
366      * @Description Broadcast receive the result of bonjour txt record for a service.
367      *
368      * @param wholeDomainName - the whole domain name
369      * @param txtMap - txt record data as a map of key/value pairs
370      * @param srcDevice source device
371      */
372     virtual void BroadcastDnsSdTxtRecordResult(const std::string &wholeDomainName,
373         const std::map<std::string, std::string> &txtMap, const WifiP2pDevice &srcDevice) const;
374     /**
375      * @Description Broadcast receive upnp service response result.
376      *
377      * @param uniqueServiceNames - the list of unique service names
378      * @param srcDevice - source device
379      */
380     virtual void BroadcastUpnpServiceResult(
381         const std::vector<std::string> &uniqueServiceNames, const WifiP2pDevice &srcDevice) const;
382 
383     /**
384      * @Description - Start the dhcp server and save the IP address to be assigned.
385      * @return true: success   false: fail
386      */
387     virtual bool StartDhcpServer();
388 
389     /**
390      * @Description - Stop the dhcp server.
391      * @return true: success   false: fail
392      */
393     virtual bool StopDhcpServer();
394 
395     virtual bool HandlerDisableRandomMac(int setmode) const;
396 private:
397     virtual void NotifyUserInvitationSentMessage(const std::string &pin, const std::string &peerAddress) const;
398     virtual void NotifyUserProvDiscShowPinRequestMessage(const std::string &pin, const std::string &peerAddress);
399     virtual void NotifyUserInvitationReceivedMessage();
400     virtual ErrCode AddClientInfo(std::vector<GcInfo> &gcInfos);
401     virtual ErrCode RemoveClientInfo(std::string mac);
402 
403 private:
404     virtual void P2pConnectByShowingPin(const WifiP2pConfigInternal &config) const;
405     bool ReinvokeGroup(WifiP2pConfigInternal &config, int networkId, const WifiP2pDevice &device) const;
406     void StopP2pDhcpClient();
407     void DoP2pArp(std::string serverIp, std::string clientIp);
408     GcInfo MatchDevInGcInfos(const std::string &deviceAddr, const std::string &groupAddr, std::vector<GcInfo> &gcInfos);
409 
410 private:
411     mutable std::mutex cbMapMutex;
412     std::map<std::string, IP2pServiceCallbacks> p2pServiceCallbacks;  /* state machine -> service callback */
413     std::string p2pIface;               /* P2P iface */
414     WifiP2pConfigInternal savedP2pConfig;    /* record P2P config when communicating with the peer device */
415     P2pMonitor &p2pMonitor;          /* P2P monitor */
416     WifiP2pGroupManager &groupManager;   /* group manager */
417     WifiP2pDeviceManager &deviceManager; /* device manager */
418     WifiP2pServiceManager &serviceManager;   /* service manager */
419     ClientCallBack clientCallBack;
420     ServerCallBack serverCallBack;
421     DhcpResultNotify *pDhcpResultNotify;
422     DhcpdInterface m_DhcpdInterface;
423     AuthorizingNegotiationRequestState &p2pAuthorizingNegotiationRequestState;
424     GroupFormedState &p2pGroupFormedState;
425     GroupNegotiationState &p2pGroupNegotiationState;
426     InvitationReceivedState &p2pInvitationReceivedState;
427     InvitationRequestState &p2pInvitationRequestState;
428     P2pDefaultState &p2pDefaultState;
429     P2pDisabledState &p2pDisabledState;
430     P2pDisablingState &p2pDisablingState;
431     P2pEnabledState &p2pEnabledState;
432     P2pEnablingState &p2pEnablingState;
433     P2pGroupFormationState &p2pGroupFormationState;
434     P2pGroupJoinState &p2pGroupJoinState;
435     P2pGroupOperatingState &p2pGroupOperatingState;
436     P2pIdleState &p2pIdleState;
437     P2pInvitingState &p2pInvitingState;
438     ProvisionDiscoveryState &p2pProvisionDiscoveryState;
439     P2pGroupRemoveState &p2pGroupRemoveState;
440     static DHCPTYPE m_isNeedDhcp;
441     std::string p2pDevIface;
442     static std::mutex m_gcJoinmutex;
443 
444 public:
445     std::vector<std::string> curClientList;
446 };
447 }  // namespace Wifi
448 }  // namespace OHOS
449 
450 #endif  // OHOS_P2P_STATE_MACHINE_H
451