1 /*
2 * Copyright (c) 2023 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 #ifdef FEATURE_P2P_SUPPORT
17 #include "wifi_p2p_manager.h"
18 #include "wifi_manager.h"
19 #include "wifi_service_manager.h"
20 #include "wifi_config_center.h"
21 #include "wifi_logger.h"
22 #include "wifi_common_event_helper.h"
23 #include "wifi_system_timer.h"
24 #include "wifi_hisysevent.h"
25 #include "p2p_define.h"
26 #ifdef OHOS_ARCH_LITE
27 #include "wifi_internal_event_dispatcher_lite.h"
28 #else
29 #include "wifi_internal_event_dispatcher.h"
30 #include "wifi_sa_manager.h"
31 #endif
32 #ifdef HDI_CHIP_INTERFACE_SUPPORT
33 #include "hal_device_manage.h"
34 #endif
35
36 DEFINE_WIFILOG_LABEL("WifiP2pManager");
37
38 namespace OHOS {
39 namespace Wifi {
40 constexpr int32_t P2P_ENABLE_WAIT_MS = 500;
WifiP2pManager()41 WifiP2pManager::WifiP2pManager()
42 {
43 WIFI_LOGI("create WifiP2pManager");
44 InitP2pCallback();
45 }
46
GetP2pCallback(void)47 IP2pServiceCallbacks& WifiP2pManager::GetP2pCallback(void)
48 {
49 return mP2pCallback;
50 }
51
AutoStartP2pService()52 ErrCode WifiP2pManager::AutoStartP2pService()
53 {
54 WifiOprMidState p2pState = WifiConfigCenter::GetInstance().GetP2pMidState();
55 WIFI_LOGI("AutoStartP2pService, current p2p state:%{public}d", p2pState);
56 if (p2pState != WifiOprMidState::CLOSED) {
57 if (p2pState == WifiOprMidState::CLOSING) {
58 return WIFI_OPT_OPEN_FAIL_WHEN_CLOSING;
59 } else {
60 return WIFI_OPT_OPEN_SUCC_WHEN_OPENED;
61 }
62 }
63
64 #ifdef HDI_CHIP_INTERFACE_SUPPORT
65 if (ifaceName.empty() && !DelayedSingleton<HalDeviceManager>::GetInstance()->CreateP2pIface(
66 std::bind(&WifiP2pManager::IfaceDestoryCallback, this, std::placeholders::_1, std::placeholders::_2),
67 ifaceName)) {
68 WIFI_LOGE("AutoStartP2pService, create iface failed!");
69 return WIFI_OPT_FAILED;
70 }
71 WifiConfigCenter::GetInstance().SetP2pIfaceName(ifaceName);
72 #endif
73
74 if (!WifiConfigCenter::GetInstance().SetP2pMidState(p2pState, WifiOprMidState::OPENING)) {
75 WIFI_LOGE("AutoStartP2pService, set p2p mid state opening failed!");
76 return WIFI_OPT_OPEN_SUCC_WHEN_OPENED;
77 }
78
79 ErrCode ret = WIFI_OPT_FAILED;
80 do {
81 if (WifiServiceManager::GetInstance().CheckAndEnforceService(WIFI_SERVICE_P2P) < 0) {
82 WIFI_LOGE("Load %{public}s service failed!", WIFI_SERVICE_P2P);
83 break;
84 }
85 IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst();
86 if (pService == nullptr) {
87 WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_P2P);
88 break;
89 }
90 ret = pService->RegisterP2pServiceCallbacks(mP2pCallback);
91 if (ret != WIFI_OPT_SUCCESS) {
92 WIFI_LOGE("Register p2p service callback failed!");
93 break;
94 }
95
96 ret = pService->EnableP2p();
97 if (ret != WIFI_OPT_SUCCESS) {
98 WIFI_LOGE("service EnableP2p failed, ret %{public}d!", static_cast<int>(ret));
99 break;
100 }
101 IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
102 if (pEnhanceService == nullptr) {
103 WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_ENHANCE);
104 break;
105 }
106 ret = pService->SetEnhanceService(pEnhanceService);
107 if (ret != WIFI_OPT_SUCCESS) {
108 WIFI_LOGE("SetEnhanceService failed, ret %{public}d!", static_cast<int>(ret));
109 break;
110 }
111 } while (false);
112 if (ret != WIFI_OPT_SUCCESS) {
113 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED);
114 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_P2P);
115 return ret;
116 }
117 std::unique_lock<std::mutex> locker(p2pEnableMutex);
118 p2pEnableCond.wait_for(locker, std::chrono::milliseconds(P2P_ENABLE_WAIT_MS));
119 #ifndef OHOS_ARCH_LITE
120 StopUnloadP2PSaTimer();
121 #endif
122 return WIFI_OPT_SUCCESS;
123 }
124
AutoStopP2pService()125 ErrCode WifiP2pManager::AutoStopP2pService()
126 {
127 WifiOprMidState p2pState = WifiConfigCenter::GetInstance().GetP2pMidState();
128 WIFI_LOGI("AutoStopP2pService, current p2p state:%{public}d", p2pState);
129 if (p2pState != WifiOprMidState::RUNNING) {
130 if (p2pState == WifiOprMidState::OPENING) {
131 return WIFI_OPT_CLOSE_FAIL_WHEN_OPENING;
132 } else {
133 return WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED;
134 }
135 }
136
137 if (!WifiConfigCenter::GetInstance().SetP2pMidState(p2pState, WifiOprMidState::CLOSING)) {
138 WIFI_LOGE("AutoStopP2pService, set p2p mid state opening failed!");
139 return WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED;
140 }
141
142 IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst();
143 if (pService == nullptr) {
144 WIFI_LOGE("AutoStopP2pService, Instance get p2p service is null!");
145 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::CLOSED);
146 WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_P2P);
147 return WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED;
148 }
149
150 ErrCode ret = pService->DisableP2p();
151 if (ret != WIFI_OPT_SUCCESS) {
152 WIFI_LOGE("service disable p2p failed, ret %{public}d!", static_cast<int>(ret));
153 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::CLOSING, WifiOprMidState::RUNNING);
154 return ret;
155 }
156 std::unique_lock<std::mutex> locker(p2pEnableMutex);
157 p2pEnableCond.wait_for(locker, std::chrono::milliseconds(P2P_ENABLE_WAIT_MS));
158 return WIFI_OPT_SUCCESS;
159 }
160
161 #ifndef OHOS_ARCH_LITE
UnloadP2PSaTimerCallback()162 static void UnloadP2PSaTimerCallback()
163 {
164 WifiSaLoadManager::GetInstance().UnloadWifiSa(WIFI_P2P_ABILITY_ID);
165 WifiManager::GetInstance().GetWifiP2pManager()->StopUnloadP2PSaTimer();
166 }
167
StopUnloadP2PSaTimer(void)168 void WifiP2pManager::StopUnloadP2PSaTimer(void)
169 {
170 WIFI_LOGI("StopUnloadP2PSaTimer! unloadP2PSaTimerId:%{public}u", unloadP2PSaTimerId);
171 std::unique_lock<std::mutex> lock(unloadP2PSaTimerMutex);
172 if (unloadP2PSaTimerId == 0) {
173 return;
174 }
175 MiscServices::TimeServiceClient::GetInstance()->StopTimer(unloadP2PSaTimerId);
176 MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(unloadP2PSaTimerId);
177 unloadP2PSaTimerId = 0;
178 return;
179 }
180
StartUnloadP2PSaTimer(void)181 void WifiP2pManager::StartUnloadP2PSaTimer(void)
182 {
183 WIFI_LOGI("StartUnloadP2PSaTimer! unloadP2PSaTimerId:%{public}u", unloadP2PSaTimerId);
184 std::unique_lock<std::mutex> lock(unloadP2PSaTimerMutex);
185 if (unloadP2PSaTimerId == 0) {
186 std::shared_ptr<WifiSysTimer> wifiSysTimer = std::make_shared<WifiSysTimer>(false, 0, true, false);
187 wifiSysTimer->SetCallbackInfo(UnloadP2PSaTimerCallback);
188 unloadP2PSaTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(wifiSysTimer);
189 int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
190 MiscServices::TimeServiceClient::GetInstance()->StartTimer(unloadP2PSaTimerId,
191 currentTime + TIMEOUT_UNLOAD_WIFI_SA);
192 WIFI_LOGI("StartUnloadP2PSaTimer success! unloadP2PSaTimerId:%{public}u", unloadP2PSaTimerId);
193 }
194 return;
195 }
196 #endif
197
CloseP2pService(void)198 void WifiP2pManager::CloseP2pService(void)
199 {
200 WIFI_LOGD("close p2p service");
201 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::CLOSED);
202 WifiConfigCenter::GetInstance().SetP2pState(static_cast<int>(P2pState::P2P_STATE_CLOSED));
203 WifiEventCallbackMsg cbMsg;
204 cbMsg.msgCode = WIFI_CBK_MSG_P2P_STATE_CHANGE;
205 cbMsg.msgData = static_cast<int>(P2pState::P2P_STATE_CLOSED);
206 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
207 #ifdef HDI_CHIP_INTERFACE_SUPPORT
208 if (!ifaceName.empty()) {
209 DelayedSingleton<HalDeviceManager>::GetInstance()->RemoveP2pIface(ifaceName);
210 ifaceName.clear();
211 WifiConfigCenter::GetInstance().SetP2pIfaceName("");
212 }
213 #endif
214 WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState();
215 #ifndef OHOS_ARCH_LITE
216 if (WifiConfigCenter::GetInstance().GetAirplaneModeState() == MODE_STATE_OPEN) {
217 WIFI_LOGI("airplaneMode not close p2p SA!");
218 return;
219 }
220 #endif
221 WIFI_LOGI("CloseP2pService, current sta state:%{public}d", staState);
222 return;
223 }
224
InitP2pCallback(void)225 void WifiP2pManager::InitP2pCallback(void)
226 {
227 using namespace std::placeholders;
228 mP2pCallback.callbackModuleName = "P2pManager";
229 mP2pCallback.OnP2pStateChangedEvent = std::bind(&WifiP2pManager::DealP2pStateChanged, this, _1);
230 mP2pCallback.OnP2pPeersChangedEvent = std::bind(&WifiP2pManager::DealP2pPeersChanged, this, _1);
231 mP2pCallback.OnP2pServicesChangedEvent = std::bind(&WifiP2pManager::DealP2pServiceChanged, this, _1);
232 mP2pCallback.OnP2pConnectionChangedEvent = std::bind(&WifiP2pManager::DealP2pConnectionChanged, this, _1);
233 mP2pCallback.OnP2pThisDeviceChangedEvent = std::bind(&WifiP2pManager::DealP2pThisDeviceChanged, this, _1);
234 mP2pCallback.OnP2pDiscoveryChangedEvent = std::bind(&WifiP2pManager::DealP2pDiscoveryChanged, this, _1);
235 mP2pCallback.OnP2pGroupsChangedEvent = std::bind(&WifiP2pManager::DealP2pGroupsChanged, this);
236 mP2pCallback.OnP2pActionResultEvent = std::bind(&WifiP2pManager::DealP2pActionResult, this, _1, _2);
237 mP2pCallback.OnConfigChangedEvent = std::bind(&WifiP2pManager::DealConfigChanged, this, _1, _2, _3);
238 mP2pCallback.OnP2pGcJoinGroupEvent = std::bind(&WifiP2pManager::DealP2pGcJoinGroup, this, _1);
239 mP2pCallback.OnP2pGcLeaveGroupEvent = std::bind(&WifiP2pManager::DealP2pGcLeaveGroup, this, _1);
240 mP2pCallback.OnP2pPrivatePeersChangedEvent = std::bind(&WifiP2pManager::DealP2pPrivatePeersChanged, this, _1);
241 return;
242 }
243
DealP2pStateChanged(P2pState state)244 void WifiP2pManager::DealP2pStateChanged(P2pState state)
245 {
246 WIFI_LOGI("DealP2pStateChanged, state: %{public}d", static_cast<int>(state));
247 WifiEventCallbackMsg cbMsg;
248 cbMsg.msgCode = WIFI_CBK_MSG_P2P_STATE_CHANGE;
249 cbMsg.msgData = static_cast<int>(state);
250 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
251 if (state == P2pState::P2P_STATE_IDLE) {
252 CloseP2pService();
253 p2pEnableCond.notify_all();
254 }
255 if (state == P2pState::P2P_STATE_STARTED) {
256 WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::OPENING, WifiOprMidState::RUNNING);
257 p2pEnableCond.notify_all();
258 WifiOprMidState staState = WifiConfigCenter::GetInstance().GetWifiMidState();
259 WIFI_LOGI("DealP2pStateChanged, current sta state:%{public}d", staState);
260 if (staState == WifiOprMidState::CLOSING || staState == WifiOprMidState::CLOSED) {
261 AutoStopP2pService();
262 }
263 }
264 if (state == P2pState::P2P_STATE_CLOSED) {
265 bool ret = WifiConfigCenter::GetInstance().SetP2pMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED);
266 if (ret) {
267 WIFI_LOGE("P2p start failed, stop wifi!");
268 AutoStopP2pService();
269 }
270 }
271 WifiCommonEventHelper::PublishP2pStateChangedEvent((int)state, "OnP2pStateChanged");
272 return;
273 }
274
DealP2pPeersChanged(const std::vector<WifiP2pDevice> & vPeers)275 void WifiP2pManager::DealP2pPeersChanged(const std::vector<WifiP2pDevice> &vPeers)
276 {
277 WifiEventCallbackMsg cbMsg;
278 cbMsg.msgCode = WIFI_CBK_MSG_PEER_CHANGE;
279 cbMsg.device = vPeers;
280 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
281 WifiCommonEventHelper::PublishP2pPeersStateChangedEvent(vPeers.size(), "OnP2pPeersChanged");
282 return;
283 }
284
DealP2pPrivatePeersChanged(const std::string & privateInfo)285 void WifiP2pManager::DealP2pPrivatePeersChanged(const std::string &privateInfo)
286 {
287 WifiEventCallbackMsg cbMsg;
288 cbMsg.msgCode = WIFI_CBK_MSG_PRIVATE_PEER_CHANGE;
289 cbMsg.privateWfdInfo = privateInfo;
290 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
291 return;
292 }
293
DealP2pServiceChanged(const std::vector<WifiP2pServiceInfo> & vServices)294 void WifiP2pManager::DealP2pServiceChanged(const std::vector<WifiP2pServiceInfo> &vServices)
295 {
296 WifiEventCallbackMsg cbMsg;
297 cbMsg.msgCode = WIFI_CBK_MSG_SERVICE_CHANGE;
298 cbMsg.serviceInfo = vServices;
299 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
300 return;
301 }
302
DealP2pConnectionChanged(const WifiP2pLinkedInfo & info)303 void WifiP2pManager::DealP2pConnectionChanged(const WifiP2pLinkedInfo &info)
304 {
305 WifiEventCallbackMsg cbMsg;
306 cbMsg.msgCode = WIFI_CBK_MSG_CONNECT_CHANGE;
307 cbMsg.p2pInfo = info;
308 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
309 WifiCommonEventHelper::PublishP2pConnStateEvent((int)info.GetConnectState(), "OnP2pConnectStateChanged");
310 WifiP2pGroupInfo group;
311 IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst();
312 if (pService == nullptr) {
313 WIFI_LOGE("Get P2P service failed!");
314 return;
315 }
316 ErrCode errCode = pService->GetCurrentGroup(group);
317 if (errCode != WIFI_OPT_SUCCESS) {
318 WIFI_LOGE("Get current group info failed!");
319 return;
320 }
321 WriteWifiP2pStateHiSysEvent(group.GetInterface(), (int32_t)info.IsGroupOwner(), (int32_t)info.GetConnectState());
322 if (info.GetConnectState() == P2pConnectedState::P2P_CONNECTED) {
323 WriteP2pKpiCountHiSysEvent(static_cast<int>(P2P_CHR_EVENT::CONN_SUC_CNT));
324 }
325 return;
326 }
327
DealP2pThisDeviceChanged(const WifiP2pDevice & info)328 void WifiP2pManager::DealP2pThisDeviceChanged(const WifiP2pDevice &info)
329 {
330 WifiEventCallbackMsg cbMsg;
331 cbMsg.msgCode = WIFI_CBK_MSG_THIS_DEVICE_CHANGE;
332 cbMsg.p2pDevice = info;
333 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
334 WifiCommonEventHelper::PublishP2pCurrentDeviceStateChangedEvent(
335 (int)info.GetP2pDeviceStatus(), "OnP2pThisDeviceChanged");
336 return;
337 }
338
DealP2pDiscoveryChanged(bool bState)339 void WifiP2pManager::DealP2pDiscoveryChanged(bool bState)
340 {
341 WifiEventCallbackMsg cbMsg;
342 cbMsg.msgCode = WIFI_CBK_MSG_DISCOVERY_CHANGE;
343 cbMsg.msgData = static_cast<int>(bState);
344 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
345 return;
346 }
347
DealP2pGroupsChanged()348 void WifiP2pManager::DealP2pGroupsChanged() __attribute__((no_sanitize("cfi")))
349 {
350 WifiEventCallbackMsg cbMsg;
351 cbMsg.msgCode = WIFI_CBK_MSG_PERSISTENT_GROUPS_CHANGE;
352 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
353 WifiCommonEventHelper::PublishP2pGroupStateChangedEvent(0, "OnP2pGroupStateChanged");
354 return;
355 }
356
DealP2pActionResult(P2pActionCallback action,ErrCode code)357 void WifiP2pManager::DealP2pActionResult(P2pActionCallback action, ErrCode code)
358 {
359 WifiEventCallbackMsg cbMsg;
360 cbMsg.msgCode = WIFI_CBK_MSG_P2P_ACTION_RESULT;
361 cbMsg.p2pAction = action;
362 cbMsg.msgData = static_cast<int>(code);
363 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
364 return;
365 }
366
DealP2pGcJoinGroup(const GcInfo & info)367 void WifiP2pManager::DealP2pGcJoinGroup(const GcInfo &info)
368 {
369 WifiEventCallbackMsg cbMsg;
370 cbMsg.msgCode = WIFI_CBK_MSG_P2P_GC_JOIN_GROUP;
371 cbMsg.gcInfo = info;
372 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
373 return;
374 }
375
DealP2pGcLeaveGroup(const GcInfo & info)376 void WifiP2pManager::DealP2pGcLeaveGroup(const GcInfo &info)
377 {
378 WifiEventCallbackMsg cbMsg;
379 cbMsg.msgCode = WIFI_CBK_MSG_P2P_GC_LEAVE_GROUP;
380 cbMsg.gcInfo = info;
381 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
382 return;
383 }
384
DealConfigChanged(CfgType type,char * data,int dataLen)385 void WifiP2pManager::DealConfigChanged(CfgType type, char* data, int dataLen)
386 {
387 if (data == nullptr || dataLen <= 0) {
388 return;
389 }
390 WifiEventCallbackMsg cbMsg;
391 cbMsg.msgCode = WIFI_CBK_MSG_CFG_CHANGE;
392 CfgInfo* cfgInfoPtr = new (std::nothrow) CfgInfo();
393 if (cfgInfoPtr == nullptr) {
394 WIFI_LOGE("DealConfigChanged: new CfgInfo failed");
395 return;
396 }
397 cfgInfoPtr->type = type;
398 char* cfgData = new (std::nothrow) char[dataLen];
399 if (cfgData == nullptr) {
400 WIFI_LOGE("DealConfigChanged: new data failed");
401 delete cfgInfoPtr;
402 cfgInfoPtr = nullptr;
403 return;
404 }
405 if (memcpy_s(cfgData, dataLen, data, dataLen) != EOK) {
406 WIFI_LOGE("DealConfigChanged: memcpy_s failed");
407 delete cfgInfoPtr;
408 cfgInfoPtr = nullptr;
409 delete[] cfgData;
410 cfgData = nullptr;
411 return;
412 }
413 cfgInfoPtr->data = cfgData;
414 cfgInfoPtr->dataLen = dataLen;
415 cbMsg.cfgInfo = cfgInfoPtr;
416 WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
417 return;
418 }
419
IfaceDestoryCallback(std::string & destoryIfaceName,int createIfaceType)420 void WifiP2pManager::IfaceDestoryCallback(std::string &destoryIfaceName, int createIfaceType)
421 {
422 WIFI_LOGI("IfaceDestoryCallback, ifaceName:%{public}s, ifaceType:%{public}d",
423 destoryIfaceName.c_str(), createIfaceType);
424 if (destoryIfaceName == ifaceName) {
425 ifaceName.clear();
426 WifiConfigCenter::GetInstance().SetP2pIfaceName("");
427 }
428 return;
429 }
430
431 } // namespace Wifi
432 } // namespace OHOS
433 #endif