• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "group_negotiation_state.h"
16 #include "mac_address.h"
17 #include "wifi_p2p_hal_interface.h"
18 #include "p2p_state_machine.h"
19 #include "wifi_logger.h"
20 #include "p2p_define.h"
21 #include "wifi_hisysevent.h"
22 #include "wifi_config_center.h"
23 
24 DEFINE_WIFILOG_P2P_LABEL("GroupNegotiationState");
25 
26 namespace OHOS {
27 namespace Wifi {
GroupNegotiationState(P2pStateMachine & stateMachine,WifiP2pGroupManager & groupMgr,WifiP2pDeviceManager & deviceMgr)28 GroupNegotiationState::GroupNegotiationState(
29     P2pStateMachine &stateMachine, WifiP2pGroupManager &groupMgr, WifiP2pDeviceManager &deviceMgr)
30     : State("GroupNegotiationState"), mProcessFunMap(), p2pStateMachine(stateMachine), groupManager(groupMgr), deviceManager(deviceMgr)
31 {}
GoInState()32 void GroupNegotiationState::GoInState()
33 {
34     Init();
35     WIFI_LOGI("             GoInState");
36 }
37 
GoOutState()38 void GroupNegotiationState::GoOutState()
39 {
40     WIFI_LOGI("             GoOutState");
41 }
42 
Init()43 void GroupNegotiationState::Init()
44 {
45     mProcessFunMap.insert(std::make_pair(
46         P2P_STATE_MACHINE_CMD::P2P_EVENT_GO_NEG_SUCCESS, &GroupNegotiationState::ProcessNegotSucessEvt));
47     mProcessFunMap.insert(std::make_pair(P2P_STATE_MACHINE_CMD::P2P_EVENT_GROUP_FORMATION_SUCCESS,
48         &GroupNegotiationState::ProcessGroupFormationSuccessEvt));
49     mProcessFunMap.insert(
50         std::make_pair(P2P_STATE_MACHINE_CMD::P2P_EVENT_GROUP_STARTED, &GroupNegotiationState::ProcessGroupStartedEvt));
51     mProcessFunMap.insert(std::make_pair(P2P_STATE_MACHINE_CMD::P2P_EVENT_GROUP_FORMATION_FAILURE,
52         &GroupNegotiationState::ProcessGroupFormationFailEvt));
53     mProcessFunMap.insert(std::make_pair(
54         P2P_STATE_MACHINE_CMD::P2P_EVENT_GO_NEG_FAILURE, &GroupNegotiationState::ProcessNegotFailEvt));
55     mProcessFunMap.insert(std::make_pair(
56         P2P_STATE_MACHINE_CMD::P2P_EVENT_INVITATION_RESULT, &GroupNegotiationState::ProcessInvitationResultEvt));
57     mProcessFunMap.insert(
58         std::make_pair(P2P_STATE_MACHINE_CMD::P2P_EVENT_GROUP_REMOVED, &GroupNegotiationState::ProcessGroupRemovedEvt));
59     mProcessFunMap.insert(
60         std::make_pair(P2P_STATE_MACHINE_CMD::CMD_REMOVE_GROUP, &GroupNegotiationState::ProcessCmdRemoveGroup));
61 }
62 
ProcessNegotSucessEvt(InternalMessagePtr msg) const63 bool GroupNegotiationState::ProcessNegotSucessEvt(InternalMessagePtr msg) const
64 {
65     WIFI_LOGI("Negotiation success: %{public}d", msg->GetMessageName());
66     return EXECUTED;
67 }
68 
ProcessGroupFormationSuccessEvt(InternalMessagePtr msg) const69 bool GroupNegotiationState::ProcessGroupFormationSuccessEvt(InternalMessagePtr msg) const
70 {
71     WIFI_LOGI("Group formation success: %{public}d", msg->GetMessageName());
72     return EXECUTED;
73 }
74 
ProcessGroupStartedEvt(InternalMessagePtr msg) const75 bool GroupNegotiationState::ProcessGroupStartedEvt(InternalMessagePtr msg) const
76 {
77     WifiP2pGroupInfo group;
78     if (!msg->GetMessageObj(group)) {
79         WIFI_LOGE("Failed to obtain the group information.");
80         return EXECUTED;
81     }
82     WifiP2pLinkedInfo p2pInfo;
83     WifiConfigCenter::GetInstance().GetP2pInfo(p2pInfo);
84     p2pInfo.SetConnectState(P2pConnectedState::P2P_CONNECTED);
85     WifiConfigCenter::GetInstance().SaveP2pInfo(p2pInfo);
86     group.SetP2pGroupStatus(P2pGroupStatus::GS_STARTED);
87     group.SetCreatorUid(WifiConfigCenter::GetInstance().GetP2pCreatorUid());
88     WifiConfigCenter::GetInstance().SaveP2pCreatorUid(-1);
89     if (p2pStateMachine.CheckIsDisplayDevice(group.GetOwner().GetDeviceAddress())) {
90         group.SetPersistentFlag(true);
91     }
92     groupManager.SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, group);
93 
94     if (groupManager.GetCurrentGroup().IsGroupOwner() &&
95         MacAddress::IsValidMac(groupManager.GetCurrentGroup().GetOwner().GetDeviceAddress().c_str())) {
96         deviceManager.GetThisDevice().SetP2pDeviceStatus(P2pDeviceStatus::PDS_CONNECTED);
97         group.SetOwner(deviceManager.GetThisDevice());
98         groupManager.SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, group);
99     }
100 
101     if (groupManager.GetCurrentGroup().IsPersistent()) {
102         p2pStateMachine.UpdateGroupManager();
103         const WifiP2pDevice &owner = groupManager.GetCurrentGroup().GetOwner();
104         WifiP2pGroupInfo copy = groupManager.GetCurrentGroup();
105         copy.SetNetworkId(groupManager.GetGroupNetworkId(owner, groupManager.GetCurrentGroup().GetGroupName()));
106         groupManager.SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, copy);
107         groupManager.AddOrUpdateGroup(groupManager.GetCurrentGroup());
108         p2pStateMachine.UpdatePersistentGroups();
109     } else {
110         WifiP2pGroupInfo copy = groupManager.GetCurrentGroup();
111         copy.SetNetworkId(TEMPORARY_NET_ID);
112         groupManager.SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, copy);
113     }
114 
115     DoDhcpInGroupStart();
116     SharedLinkManager::IncreaseSharedLink();
117     if (WifiP2PHalInterface::GetInstance().SetP2pPowerSave(group.GetInterface(), true) != WIFI_HAL_OPT_OK) {
118         WIFI_LOGE("SetP2pPowerSave() failed!");
119     }
120     p2pStateMachine.SwitchState(&p2pStateMachine.p2pGroupFormedState);
121     return EXECUTED;
122 }
123 
DoDhcpInGroupStart(void) const124 void GroupNegotiationState::DoDhcpInGroupStart(void) const
125 {
126     if (groupManager.GetCurrentGroup().IsGroupOwner()) {
127         if (!p2pStateMachine.StartDhcpServer()) {
128             WIFI_LOGE("failed to startup Dhcp server.");
129             p2pStateMachine.SendMessage(static_cast<int>(P2P_STATE_MACHINE_CMD::CMD_REMOVE_GROUP));
130         }
131         if (WifiErrorNo::WIFI_HAL_OPT_OK !=
132             WifiP2PHalInterface::GetInstance().SetP2pGroupIdle(groupManager.GetCurrentGroup().GetInterface(), 0)) {
133             WIFI_LOGE("failed to set GO Idle time.");
134         }
135     } else {
136         if (WifiErrorNo::WIFI_HAL_OPT_OK !=
137             WifiP2PHalInterface::GetInstance().SetP2pGroupIdle(groupManager.GetCurrentGroup().GetInterface(), 0)) {
138             WIFI_LOGE("failed to set GC Idle time.");
139         }
140 
141         /* GC start DHCP Client. */
142         if (p2pStateMachine.GetIsNeedDhcp() == DHCPTYPE::NO_DHCP) {
143             p2pStateMachine.BroadcastP2pConnectionChanged();
144         } else {
145             p2pStateMachine.StartDhcpClientInterface();
146         }
147         const WifiP2pDevice &owner = groupManager.GetCurrentGroup().GetOwner();
148         WifiP2pDevice device = deviceManager.GetDevices(owner.GetDeviceAddress());
149         if (device.IsValid()) {
150             device.SetRandomDeviceAddress(owner.GetRandomDeviceAddress());
151             device.SetP2pDeviceStatus(P2pDeviceStatus::PDS_CONNECTED);
152             WifiP2pGroupInfo copy = groupManager.GetCurrentGroup();
153             copy.SetOwner(device);
154             groupManager.SetCurrentGroup(WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO, copy);
155             WIFI_LOGI("ProcessGroupStartedEvt %{private}s %{private}s",
156                 device.GetDeviceAddress().c_str(), device.GetRandomDeviceAddress().c_str());
157             deviceManager.UpdateDeviceStatus(owner.GetDeviceAddress(), P2pDeviceStatus::PDS_CONNECTED);
158             p2pStateMachine.BroadcastP2pPeersChanged();
159         } else {
160             WIFI_LOGE("fail:No GO device information is found.");
161         }
162     }
163 }
164 
ProcessGroupFormationFailEvt(InternalMessagePtr msg) const165 bool GroupNegotiationState::ProcessGroupFormationFailEvt(InternalMessagePtr msg) const
166 {
167     int status = msg->GetParam1();
168     WIFI_LOGW("Group formation failure. Error code: %{public}d", status);
169     return EXECUTED;
170 }
171 
ProcessNegotFailEvt(InternalMessagePtr msg) const172 bool GroupNegotiationState::ProcessNegotFailEvt(InternalMessagePtr msg) const
173 {
174     int status = msg->GetParam1();
175     WIFI_LOGE("Negotiation failure. Error code: %{public}d", status);
176     WriteP2pConnectFailedHiSysEvent(status, static_cast<int>(P2P_ERROR_RES::NEGO_FAILURE));
177     p2pStateMachine.DealGroupCreationFailed();
178     p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
179     return EXECUTED;
180 }
181 
ProcessInvitationResultEvt(InternalMessagePtr msg) const182 bool GroupNegotiationState::ProcessInvitationResultEvt(InternalMessagePtr msg) const
183 {
184     P2pStatus status = static_cast<P2pStatus>(msg->GetParam1());
185     WIFI_LOGI("Invitation result is %{public}d", msg->GetParam1());
186     if (status == P2pStatus::SUCCESS) {
187         WIFI_LOGI("Invitation is succeeded.");
188         return EXECUTED;
189     }
190 
191     if (P2pStatus::UNKNOWN_P2P_GROUP == status) {
192         int networkId = p2pStateMachine.savedP2pConfig.GetNetId();
193         if (networkId >= 0) {
194             groupManager.RemoveClientFromGroup(networkId, p2pStateMachine.savedP2pConfig.GetDeviceAddress());
195         }
196         p2pStateMachine.savedP2pConfig.SetNetId(-1);
197         p2pStateMachine.P2pConnectByShowingPin(p2pStateMachine.savedP2pConfig);
198     } else if (P2pStatus::INFORMATION_IS_CURRENTLY_UNAVAILABLE == status) {
199         p2pStateMachine.savedP2pConfig.SetNetId(-1);
200         p2pStateMachine.P2pConnectByShowingPin(p2pStateMachine.savedP2pConfig);
201     } else if (P2pStatus::NO_COMMON_CHANNELS == status) {
202         WIFI_LOGE("fail:There is no common channel.");
203     } else {
204         p2pStateMachine.DealGroupCreationFailed();
205         p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
206     }
207     return EXECUTED;
208 }
ProcessGroupRemovedEvt(InternalMessagePtr msg) const209 bool GroupNegotiationState::ProcessGroupRemovedEvt(InternalMessagePtr msg) const
210 {
211     /**
212      * The group has been removed. The possible cause is that an exception occurs during the connection.
213      */
214     WIFI_LOGI("Recv event: %{public}d. The group has been removed.", msg->GetMessageName());
215     p2pStateMachine.DealGroupCreationFailed();
216     p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
217     return EXECUTED;
218 }
219 
ProcessCmdRemoveGroup(InternalMessagePtr msg) const220 bool GroupNegotiationState::ProcessCmdRemoveGroup(InternalMessagePtr msg) const
221 {
222     std::string ifName = p2pStateMachine.p2pDevIface;
223     if (ifName.empty()) {
224         WIFI_LOGE("invalid ifname on ProcessCmdRemoveGroup");
225         return EXECUTED;
226     }
227     p2pStateMachine.p2pDevIface = "";
228     WifiErrorNo ret = WifiP2PHalInterface::GetInstance().GroupRemove(ifName);
229     if (ret) {
230         WIFI_LOGE("P2P group (%{public}s) removal failed.", ifName.c_str());
231         p2pStateMachine.ChangeConnectedStatus(P2pConnectedState::P2P_DISCONNECTED);
232         p2pStateMachine.BroadcastActionResult(P2pActionCallback::RemoveGroup, WIFI_OPT_FAILED);
233     } else {
234         WIFI_LOGI("The P2P group (%{public}s) is successfully removed.", ifName.c_str());
235         p2pStateMachine.ChangeConnectedStatus(P2pConnectedState::P2P_DISCONNECTED);
236         p2pStateMachine.BroadcastActionResult(P2pActionCallback::RemoveGroup, WIFI_OPT_SUCCESS);
237         ret = WifiP2PHalInterface::GetInstance().P2pFlush();
238         if (ret != WifiErrorNo::WIFI_HAL_OPT_OK) {
239             WIFI_LOGE("call P2pFlush() failed, ErrCode: %{public}d", static_cast<int>(ret));
240         }
241     }
242     p2pStateMachine.SwitchState(&p2pStateMachine.p2pIdleState);
243     return EXECUTED;
244 }
245 
ExecuteStateMsg(InternalMessagePtr msg)246 bool GroupNegotiationState::ExecuteStateMsg(InternalMessagePtr msg)
247 {
248     if (msg == nullptr) {
249         WIFI_LOGE("fatal error!");
250         return NOT_EXECUTED;
251     }
252     int msgName = msg->GetMessageName();
253     auto iter = mProcessFunMap.find(static_cast<P2P_STATE_MACHINE_CMD>(msgName));
254     if (iter == mProcessFunMap.end()) {
255         return NOT_EXECUTED;
256     }
257     if ((this->*(iter->second))(msg)) {
258         return EXECUTED;
259     } else {
260         return NOT_EXECUTED;
261     }
262 }
263 }  // namespace Wifi
264 }  // namespace OHOS
265