1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "provision_discovery_state.h"
16 #include "p2p_state_machine.h"
17 #include "wifi_p2p_temp_disc_event.h"
18 #include "wifi_p2p_hal_interface.h"
19 #include "wifi_logger.h"
20 #include "wifi_hisysevent.h"
21 
22 DEFINE_WIFILOG_P2P_LABEL("ProvisionDiscoveryState");
23 
24 namespace OHOS {
25 namespace Wifi {
ProvisionDiscoveryState(P2pStateMachine & stateMachine,WifiP2pGroupManager & setGroupMgr,WifiP2pDeviceManager & setDeviceMgr)26 ProvisionDiscoveryState::ProvisionDiscoveryState(P2pStateMachine &stateMachine, WifiP2pGroupManager &setGroupMgr,
27     WifiP2pDeviceManager &setDeviceMgr)
28     : State("ProvisionDiscoveryState"),
29       p2pStateMachine(stateMachine),
30       groupManager(setGroupMgr),
31       deviceManager(setDeviceMgr)
32 {}
GoInState()33 void ProvisionDiscoveryState::GoInState()
34 {
35     WIFI_LOGI("             GoInState");
36     Init();
37     if (WifiErrorNo::WIFI_HAL_OPT_OK !=
38         WifiP2PHalInterface::GetInstance().ProvisionDiscovery(p2pStateMachine.savedP2pConfig)) {
39         WIFI_LOGE("Failed to invoke the provision discovery flow.");
40         p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
41     }
42 }
43 
GoOutState()44 void ProvisionDiscoveryState::GoOutState()
45 {
46     WIFI_LOGI("             GoOutState");
47 }
48 
Init()49 void ProvisionDiscoveryState::Init()
50 {
51     mProcessFunMap.insert(
52         std::make_pair(P2P_STATE_MACHINE_CMD::CMD_DEVICE_DISCOVERS, &ProvisionDiscoveryState::ProcessCmdDiscoverPeer));
53     mProcessFunMap.insert(
54         std::make_pair(P2P_STATE_MACHINE_CMD::CMD_DISCOVER_SERVICES, &ProvisionDiscoveryState::ProcessCmdDiscServices));
55     mProcessFunMap.insert(
56         std::make_pair(P2P_STATE_MACHINE_CMD::CMD_START_LISTEN, &ProvisionDiscoveryState::ProcessCmdStartListen));
57     mProcessFunMap.insert(std::make_pair(
58         P2P_STATE_MACHINE_CMD::P2P_EVENT_PROV_DISC_PBC_RESP, &ProvisionDiscoveryState::ProcessProvDiscPbcRspEvt));
59     mProcessFunMap.insert(std::make_pair(
60         P2P_STATE_MACHINE_CMD::P2P_EVENT_PROV_DISC_ENTER_PIN, &ProvisionDiscoveryState::ProcessProvDiscEnterPinEvt));
61     mProcessFunMap.insert(std::make_pair(
62         P2P_STATE_MACHINE_CMD::P2P_EVENT_PROV_DISC_SHOW_PIN, &ProvisionDiscoveryState::ProcessProvDiscShowPinEvt));
63     mProcessFunMap.insert(std::make_pair(
64         P2P_STATE_MACHINE_CMD::P2P_EVENT_PROV_DISC_FAILURE, &ProvisionDiscoveryState::ProcessProvDiscFailEvt));
65     mProcessFunMap.insert(std::make_pair(
66         P2P_STATE_MACHINE_CMD::CMD_CANCEL_CONNECT, &ProvisionDiscoveryState::ProcessCmdCancelConnect));
67 }
68 
ProcessCmdDiscoverPeer(InternalMessagePtr msg) const69 bool ProvisionDiscoveryState::ProcessCmdDiscoverPeer(InternalMessagePtr msg) const
70 {
71     WIFI_LOGI("recv CMD: %{public}d", msg->GetMessageName());
72     p2pStateMachine.BroadcastActionResult(P2pActionCallback::DiscoverDevices, ErrCode::WIFI_OPT_FAILED);
73     return EXECUTED;
74 }
75 
ProcessCmdDiscServices(InternalMessagePtr msg) const76 bool ProvisionDiscoveryState::ProcessCmdDiscServices(InternalMessagePtr msg) const
77 {
78     WIFI_LOGI("recv CMD: %{public}d", msg->GetMessageName());
79     p2pStateMachine.BroadcastActionResult(P2pActionCallback::DiscoverServices, ErrCode::WIFI_OPT_FAILED);
80     return EXECUTED;
81 }
82 
ProcessCmdStartListen(InternalMessagePtr msg) const83 bool ProvisionDiscoveryState::ProcessCmdStartListen(InternalMessagePtr msg) const
84 {
85     WIFI_LOGI("recv CMD: %{public}d", msg->GetMessageName());
86     p2pStateMachine.BroadcastActionResult(P2pActionCallback::StartP2pListen, ErrCode::WIFI_OPT_FAILED);
87     return EXECUTED;
88 }
89 
ProcessProvDiscPbcRspEvt(InternalMessagePtr msg) const90 bool ProvisionDiscoveryState::ProcessProvDiscPbcRspEvt(InternalMessagePtr msg) const
91 {
92     WifiP2pTempDiscEvent provDisc;
93     if (!msg->GetMessageObj(provDisc)) {
94         WIFI_LOGD("Invalid argument provDisc");
95         return EXECUTED;
96     }
97 
98     const WifiP2pDevice &device = provDisc.GetDevice();
99     if (device.IsValid() && p2pStateMachine.savedP2pConfig.GetDeviceAddress() != device.GetDeviceAddress()) {
100         WIFI_LOGD("error:Device mismatch");
101         return EXECUTED;
102     }
103 
104     if (p2pStateMachine.savedP2pConfig.GetWpsInfo().GetWpsMethod() == WpsMethod::WPS_METHOD_PBC) {
105         p2pStateMachine.P2pConnectByShowingPin(p2pStateMachine.savedP2pConfig);
106         p2pStateMachine.SwitchState(&p2pStateMachine.p2pGroupNegotiationState);
107     }
108     return EXECUTED;
109 }
110 
ProcessProvDiscEnterPinEvt(InternalMessagePtr msg) const111 bool ProvisionDiscoveryState::ProcessProvDiscEnterPinEvt(InternalMessagePtr msg) const
112 {
113     WifiP2pTempDiscEvent provDisc;
114 
115     if (!msg->GetMessageObj(provDisc)) {
116         WIFI_LOGD("Invalid argument provDisc");
117         return EXECUTED;
118     }
119     const WifiP2pDevice &device = provDisc.GetDevice();
120 
121     if (device.IsValid() && p2pStateMachine.savedP2pConfig.GetDeviceAddress() != device.GetDeviceAddress()) {
122         WIFI_LOGD("error:Device mismatch");
123         return EXECUTED;
124     }
125 
126     if (p2pStateMachine.savedP2pConfig.GetWpsInfo().GetWpsMethod() == WpsMethod::WPS_METHOD_KEYPAD) {
127         if (!p2pStateMachine.savedP2pConfig.GetWpsInfo().GetPin().empty()) {
128             p2pStateMachine.P2pConnectByShowingPin(p2pStateMachine.savedP2pConfig);
129             p2pStateMachine.SwitchState(&p2pStateMachine.p2pGroupNegotiationState);
130         } else {
131             p2pStateMachine.SwitchState(&p2pStateMachine.p2pAuthorizingNegotiationRequestState);
132         }
133     }
134     return EXECUTED;
135 }
136 
ProcessProvDiscShowPinEvt(InternalMessagePtr msg) const137 bool ProvisionDiscoveryState::ProcessProvDiscShowPinEvt(InternalMessagePtr msg) const
138 {
139     WifiP2pTempDiscEvent provDisc;
140 
141     if (!msg->GetMessageObj(provDisc)) {
142         WIFI_LOGD("Invalid argument provDisc");
143         return EXECUTED;
144     }
145     const WifiP2pDevice &device = provDisc.GetDevice();
146 
147     if (!device.IsValid() || p2pStateMachine.savedP2pConfig.GetDeviceAddress() != device.GetDeviceAddress()) {
148         WIFI_LOGD("error:Device mismatch");
149         return EXECUTED;
150     }
151 
152     if (p2pStateMachine.savedP2pConfig.GetWpsInfo().GetWpsMethod() == WpsMethod::WPS_METHOD_DISPLAY) {
153         WpsInfo wps = p2pStateMachine.savedP2pConfig.GetWpsInfo();
154         wps.SetPin(provDisc.GetPin());
155         p2pStateMachine.savedP2pConfig.SetWpsInfo(wps);
156         p2pStateMachine.P2pConnectByShowingPin(p2pStateMachine.savedP2pConfig);
157         p2pStateMachine.NotifyUserInvitationSentMessage(provDisc.GetPin(), device.GetDeviceAddress());
158         p2pStateMachine.SwitchState(&p2pStateMachine.p2pGroupNegotiationState);
159     }
160     return EXECUTED;
161 }
162 
ProcessProvDiscFailEvt(InternalMessagePtr msg) const163 bool ProvisionDiscoveryState::ProcessProvDiscFailEvt(InternalMessagePtr msg) const
164 {
165     WIFI_LOGI("recv event: %{public}d", msg->GetMessageName());
166     p2pStateMachine.DealGroupCreationFailed();
167     p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
168     return EXECUTED;
169 }
170 
ProcessCmdCancelConnect(InternalMessagePtr msg) const171 bool ProvisionDiscoveryState::ProcessCmdCancelConnect(InternalMessagePtr msg) const
172 {
173     WIFI_LOGI("recv event: %{public}d", msg->GetMessageName());
174     WifiP2PHalInterface::GetInstance().CancelConnect();
175     p2pStateMachine.DealGroupCreationFailed();
176     p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
177     p2pStateMachine.BroadcastActionResult(P2pActionCallback::P2pCancelConnect, ErrCode::WIFI_OPT_SUCCESS);
178     return EXECUTED;
179 }
180 
ExecuteStateMsg(InternalMessagePtr msg)181 bool ProvisionDiscoveryState::ExecuteStateMsg(InternalMessagePtr msg)
182 {
183     if (msg == nullptr) {
184         WIFI_LOGE("fatal error!");
185         return NOT_EXECUTED;
186     }
187     int msgName = msg->GetMessageName();
188     auto iter = mProcessFunMap.find(static_cast<P2P_STATE_MACHINE_CMD>(msgName));
189     if (iter == mProcessFunMap.end()) {
190         return NOT_EXECUTED;
191     }
192     if ((this->*(iter->second))(msg)) {
193         return EXECUTED;
194     } else {
195         return NOT_EXECUTED;
196     }
197 }
198 }  // namespace Wifi
199 }  // namespace OHOS
200